bash脚本里怎么比字符串?几个实用写法直接抄

在写 bash 脚本处理表格数据时,经常要判断两列内容是否一致、某字段是不是空、或者某个值是不是预期的 'yes'、'true'、'completed'——这时候就得比较字符串。别总想着用 == 就完事,一不小心就翻车。

最常用的:双中括号 + ==

推荐用 [[ ]],它比单中括号 [ ] 更安全,支持模式匹配,也不会被空格或特殊字符坑:

name="Alice"
if [[ "$name" == "Alice" ]]; then
  echo "找到本人"
fi

注意引号不能省!比如 $name 没引号,遇到带空格的值(如 name="John Doe")就会报错或误判。

区分大小写?默认就是区分的

下面这行不会输出:

if [[ "HELLO" == "hello" ]]; then
  echo "相等"
fi

想忽略大小写?加个 shopt -s nocaseglob 不太直观,更简单的是转成统一大小写再比:

str1="Hello"
str2="HELLO"
if [[ "${str1,,}" == "${str2,,}" ]]; then
  echo "忽略大小写,相等"
fi

${str,,} 是 bash 4.0+ 的语法,把字符串全转小写;${str^^} 是全转大写。

检查是不是空字符串

表格里常有空白单元格,对应到脚本可能是空值或只含空格:

cell="   "
# 去掉首尾空格后判断是否为空
if [[ -z "${cell##[[:space:]]*}" ]] || [[ -z "${cell%%[[:space:]]*}" ]]; then
  echo "这格是空的(或只有空格)"
fi

更清爽的写法是先 trim 再判断:

trimmed=$(echo "$cell" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
if [[ -z "$trimmed" ]]; then
  echo "真·空"
fi

匹配通配符:比如判断是不是以 "ERR" 开头

处理日志表格时很常见:

status="ERR_timeout"
if [[ "$status" == ERR* ]]; then
  echo "出错了"
fi

注意:这里不用引号包住 ERR*,否则就变成字面匹配了;但左边变量一定要引号。

等于多个值之一?用 case 更清晰

比如表格中“状态”列可能是 pending、running、done、failed:

case "$status" in
  pending|running)
    echo "还在跑"
    ;;
  done|completed)
    echo "搞定"
    ;;
  *)
    echo "未知状态:$status"
    ;;
esac

比连写好几个 elif [[ ... ]] 干净多了。

小提醒:别在 if [ ] 里用 ==

旧式单中括号 [ ] 只认 =,写成 == 可能被当字符串字面量,导致逻辑错乱:

if [ "$a" == "$b" ]; then  # ❌ 不可靠,部分 shell 当作两个参数
if [ "$a" = "$b" ]; then   # ✅ 安全写法(但还是建议用 [[ ]]