shell脚本中不区分大小写的子字符串搜索

shell脚本中不区分大小写的子字符串搜索

如何编写一个 shell 脚本来执行命令输出的不区分大小写的子字符串匹配?

答案1

如果设置shell 选项,则可以bash使用正则表达式运算符本机执行不区分大小写的子字符串匹配。例如=~nocasematch

s1="hElLo WoRlD"
s2="LO"

shopt -s nocasematch

[[ $s1 =~ $s2 ]] && echo "match" || echo "no match"
match

s1="gOoDbYe WoRlD"
[[ $s1 =~ $s2 ]] && echo "match" || echo "no match"
no match

答案2

首先,这是一个不忽略大小写的简单示例脚本:

#!/bin/bash
if [ $(echo hello) == hello ]; then
    echo it works
fi

尝试更改右侧的字符串 hello ,它应该不再 echo it works。尝试echo hello用您选择的命令替换。如果你想忽略大小写,并且两个字符串都不包含换行符,那么你可以使用 grep:

#!/bin/bash
if echo Hello | grep -iqF hello; then
    echo it works
fi

这里的关键是您将命令输出通过管道传输到grep.该if语句测试管道中最右边命令的退出状态 - 在本例中为 grep。当且仅当 Grep 找到匹配项时才会成功退出。

grep 的选项-i表示忽略大小写。
-q选项表示在第一次匹配后不发出输出并退出。
-F选项表示将参数视为字符串而不是正则表达式。

请注意,第一个示例使用了允许直接比较和各种有用的运算符。第二种形式只是执行命令并测试它们的退出状态。[ expression ]

答案3

needle对于变量值中变量值的区分大小写的字符串搜索haystack

case "$haystack" in
  *"$needle"*) echo "present";
  *) echo "absent";
esac

对于不区分大小写的字符串搜索,请将两者转换为相同的大小写。

uc_needle=$(printf %s "$needle" | tr '[:lower:]' '[:upper:]' ; echo .); uc_needle=${uc_needle%.}
uc_haystack=$(printf %s "$haystack" | tr '[:lower:]' '[:upper:]' ; echo .); uc_haystack=${uc_haystack%.}
case "$uc_haystack" in
  *"$uc_needle"*) echo "present";;
  *) echo "absent";;
esac

请注意,trGNU coreutils 不支持多字节语言环境(例如UTF-8)。要使用多字节语言环境,请改用 awk。如果您要使用 awk,您可以让它进行字符串比较,而不仅仅是转换。

if awk 'BEGIN {exit !index(toupper(ARGV[2]), toupper(ARGV[1]))}' "$needle" "$haystack"; then
  echo "present"
else
  echo "absent"
fi

BusyBoxtr不支持该语法;你可以用它代替。 BusyBox 不支持非 ASCII 语言环境。[:CLASS:]tr a-z A-Z

在 bash(但不是 sh)4.0+ 版本中,有一个用于大小写转换的内置语法,以及一个更简单的字符串匹配语法。

if [[ "${haystack^^}" = *"${needle^^}"* ]]; then
  echo "present"
else
  echo "absent"
esac

相关内容