linux shell 编程:字符串比较详细解释

介绍

Shell 分 Bash / sh,字符串比较用 test 命令([ ] 是 test 的简写),[[ ]] 是 bash 增强版,推荐优先用 [[ ]],语法更安全,不用处理引号、空格问题。

[ ] 和 [[ ]] 区别

  1. [ ]:POSIX 标准,兼容 sh/dash,不支持正则、不支持通配匹配,变量必须双引号,语法严格。
  2. [[ ]]:bash 扩展,语法容错强,自动处理空格,支持 == 通配、=~ 正则,推荐写bash脚本优先用。

基础语法

写法1:test 原生,POSIX 标准,所有shell都支持

test "str1" = "str2"
[ "str1" = "str2" ]

写法2:bash 增强双中括号(推荐)

注意:仅bash可用

[[ "str1" == "str2" ]]

坑

  1. [ ] 里面两边必须留空格,["a"="b"] 直接报错
  2. = 两边也要空格:[ "a"="b" ] 错误;[ "a" = "b" ] 正确
  3. 变量一定要加双引号 [ "$var" = "abc" ],防止变量为空/带空格时语法崩溃
  4. == 在 [ ] 里不是等于,只是 POSIX test 的字符串字面量,[ ] 比较相等只用 =;[[ ]] 才支持 ==

字符串比较运算符

运算符 含义 适用
str1 = str2 字符串相等(完全一样) [ ] / [[ ]]
str1 != str2 字符串不相等 [ ] / [[ ]]
-z str 字符串长度为0(空字符串) [ ] / [[ ]]
-n str 字符串长度不为0(非空) [ ] / [[ ]]
str1 == pattern 模式匹配(支持通配符 *, ?) 仅 [[ ]]
str1 =~ regex 正则表达式匹配 仅 [[ ]] bash 3.0+

注意:

  • Shell 没有 > < 直接比较字符串大小,[ "a" > "b" ] 会被当成重定向!

  • 字符串字典序比较:[[ "apple" > "banana" ]](仅双中括号可用)

例子

1. 判断相等 / 不等

#!/bin/bash
name="linux"

# 相等判断
if [[ "$name" == "linux" ]]; then
    echo "字符串相等"
fi

# 不相等
if [[ "$name" != "windows" ]]; then
    echo "字符串不相等"
fi

2. 判断空字符串 -z -n

var=""
# -z 为空
if [[ -z "$var" ]]; then
    echo "var 是空字符串"
fi

var="hello"
# -n 非空
if [[ -n "$var" ]]; then
    echo "var 不为空"
fi

坑:var=" " 带空格不是空!-z 判断的是字符长度,空格也算字符。

3. [[ ]] 通配符模式匹配(* ?)

str="hello123"
# 以 hello 开头
if [[ "$str" == hello* ]]; then
    echo "以hello开头"
fi

# 第二个字符是 e
if [[ "$str" == h?llo* ]]; then
    echo "匹配通配符"
fi

解释:通配符模式不要加引号,加引号会当成普通字符串而不是模式。

4. [[ ]] 正则匹配 =~

str="abc123"
# 判断是否包含数字
if [[ "$str" =~ [0-9] ]]; then
    echo "字符串包含数字"
fi

注意:正则不要加引号,引号会把正则表达式当成普通文本。

5. 字典序比较(字母先后)

# 比较字典序,a < b
if [[ "apple" < "banana" ]]; then
    echo "apple 在字母顺序上小于 banana"
fi

坑总结

  1. ❌ [ $a = "abc" ]:变量没引号,$a 为空会变成 [ = "abc" ] 语法报错
    ✅ [ "$a" = "abc" ]
  2. ❌ ["a"="b"]:缺少空格
    ✅ [ "a" = "b" ]
  3. ❌ [ "$s" == "123" ]:POSIX [ ] 规范里相等用 =,虽然bash很多版本兼容==,不推荐
  4. ❌ [ $str =~ [0-9] ]:[ ] 不支持正则 =~
  5. ❌ [[ "$str" == "hello*" ]]:模式加引号,* 失去通配作用,变成字面星号
  6. ❌ [ "a" > "b" ]:单中括号里 > 被识别为文件重定向,会创建文件 b!

多条件组合

在 [[ ]] 中:

  • && 逻辑与
  • || 逻辑或
    str="test123"
    if [[ -n "$str" && "$str" == test* ]]; then
      echo "非空,并且以test开头"
    fi
    

原文出处:/show_1GW46uubfC8b.html