在Shell脚本中进行大小写不敏感的字符串比较
在Bash中,可以使用参数扩展来将字符串修改为全小写/全大写:
var1=TesT var2=tEst echo ${var1,,} ${var2,,} echo ${var1^^} ${var2^^}
至少有一种不需要使用shopt选项的回答。这样你就可以忽略大小写地比较两个字符串,并在同一个测试中比较另外两个带有大小写的字符串。谢谢。
这在Bash 4中是新功能吗?至少在Bash 3.2.51(在OS X 10.9中使用)中是无效的 - 第一个echo
语句的结果为:-bash: ${var1,,}: bad substitution
这种不区分大小写的比较实现容易出现本地化问题(比如土耳其语的问题)。我不知道shopt -s nocasematch
是如何实现的,但通常这种"语言级"的解决方案会正确处理这个问题。
我在macOS 10.13.6上使用的是Bash 3.2.57,结果也是相同的错误
./anothertest.sh: line 4: ${var1,,}: bad substitution ./anothertest.sh: line 5: ${var1^^}: bad substitution
在bash 4.4.20
中,,,
和^^
都可行,但在zsh 5.4.2
(ubuntu 18.04)中都不可行。
大小写不敏感比较字符串在shell脚本中是一个常见的需求。然而,在某些情况下,这可能会导致问题。上述内容提供了一种解决方法,即在Bash 4或更新版本中使用字符串转换为小写字母的方法进行比较。
解决方案是使用以下代码片段:
if [ "${var1,,}" = "${var2,,}" ]; then echo ":)" fi
这样做的效果是将两个字符串都转换为小写字母,然后比较结果。然而,这种方法只适用于Bash 4或更新版本。
出现这个问题的原因是,默认情况下,许多操作系统(如Mac OS X 10.11)上安装的Bash版本可能较旧,不支持这种大小写不敏感的比较方法。因此,如果你的脚本需要在不同的Mac上运行,那么默认的Bash版本可能无法满足需要。
为了解决这个问题,有几种可能的方法。一种方法是手动安装Bash 4或更新版本,以确保在所有系统上都能使用这种比较方法。然而,这种方法可能不适用于所有情况,特别是在需要保证可移植性的情况下。
另一种方法是遵循POSIX shell标准,这样可以保证在任何情况下都能找到一个可用的shell版本。然而,这种方法可能需要对脚本进行一些修改,以适应POSIX标准的限制。
总之,虽然在Bash 4或更新版本中使用字符串转换为小写字母的方法可以很方便地实现大小写不敏感的比较,但在一些情况下可能需要考虑可移植性和系统兼容性的问题。
无论使用哪种shell,都可以通过设置nocasematch来实现大小写不敏感的字符串比较。在bash中,可以使用shopt命令设置nocasematch选项,然后使用case语句进行比较。如果使用其他shell,则需要使用awk命令进行比较。下面是使用bash和awk的示例代码:
如果使用bash:
str1="MATCH" str2="match" shopt -s nocasematch case "$str1" in $str2 ) echo "match";; *) echo "no match";; esac
如果使用其他shell,可以使用awk进行比较:
str1="MATCH" str2="match" awk -vs1="$str1" -vs2="$str2" 'BEGIN { if ( tolower(s1) == tolower(s2) ){ print "match" } }'
对于使用if语句比较字符串的情况,shopt方法需要使用双方括号[[]]形式的条件语句,而不是单方括号[]形式的条件语句。此外,shopt方法还可以使==、=~等字符串比较操作符实现大小写不敏感比较。
在比较完成后,最好执行shopt -u nocasematch命令将nocasematch设置恢复为默认值。
如果希望保存和恢复nocasematch设置,可以使用SHELLNOCASEMATCH=`shopt -p nocasematch`保存设置,然后使用shopt -s nocasematch进行修改,比较完成后使用$SHELLNOCASEMATCH进行恢复。
在bash脚本中使用awk的比较,可以使用if命令结合awk进行判断,例如:if awk -vs1="$str1" -vs2="$str2" 'BEGIN {exit (tolower(s1)!=tolower(s2))}'; then echo "'$str1' and '$str2' match"; fi。
总结起来,无论使用哪种shell,都可以通过设置nocasematch选项或使用awk命令实现大小写不敏感的字符串比较。