String shell脚本中字符串的不区分大小写比较

String shell脚本中字符串的不区分大小写比较,string,shell,compare,case-insensitive,String,Shell,Compare,Case Insensitive,=操作符用于比较shell脚本中的两个字符串。然而,我想比较两个字符串忽略情况下,如何才能做到这一点?是否有任何标准命令用于此操作?shopt-s nocaseglob一种方法是将两个字符串转换为上限或下限: test $(echo "string" | /bin/tr '[:upper:]' '[:lower:]') = $(echo "String" | /bin/tr '[:upper:]' '[:lower:]') && echo same || echo differe

=
操作符用于比较shell脚本中的两个字符串。然而,我想比较两个字符串忽略情况下,如何才能做到这一点?是否有任何标准命令用于此操作?

shopt-s nocaseglob

一种方法是将两个字符串转换为上限或下限:

test $(echo "string" | /bin/tr '[:upper:]' '[:lower:]') = $(echo "String" | /bin/tr '[:upper:]' '[:lower:]') && echo same || echo different
另一种方法是使用grep:

echo "string" | grep -qi '^String$' && echo same || echo different
如果你有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"
  }
}'

grep
有一个
-i
标志,表示不区分大小写,所以让它告诉您var2是否在var1中

var1=match 
var2=MATCH 
if echo $var1 | grep -i "^${var2}$" > /dev/null ; then
    echo "MATCH"
fi

保存
nocasematch
的状态(如果某些其他功能取决于它是否被禁用):

请注意
local
仅在函数内部需要。
还有,
;当
set-e
打开且
$(shopt-p nocasematch)
失败时,true
部分将阻止shell退出(因为没有设置nocasematch)


对于KornShell,我使用内置的typeset命令(-l表示小写,-u表示大写)


在Bash中,可以使用参数展开将字符串修改为所有小写/大写:

var1=TesT
var2=tEst

echo ${var1,,} ${var2,,}
echo ${var1^^} ${var2^^}

所有这些答案都忽略了最简单、最快捷的方法(只要您有Bash 4):


您所做的只是将两个字符串转换为小写并比较结果。

以下是我使用tr的解决方案:

var1=match
var2=MATCH
var1=`echo $var1 | tr '[A-Z]' '[a-z]'`
var2=`echo $var2 | tr '[A-Z]' '[a-z]'`
if [ "$var1" = "$var2" ] ; then
  echo "MATCH"
fi

如果要执行不区分大小写的行比较,非常容易:

str1="MATCH"
str2="match"

if [[ $(fgrep -ix $str1 <<< $str2) ]]; then
    echo "case-insensitive match";
fi
str1=“匹配”
str2=“匹配”

如果[[$(fgrep-ix$str1For
zsh
的语法略有不同,但仍然比此处的大多数答案短:

> str1='mAtCh'
> str2='MaTcH'
> [[ "$str1:u" = "$str2:u" ]] && echo 'Strings Match!'
Strings Match!
>
这将在比较之前将两个字符串转换为大写


另一种方法使用zsh,它允许我们通过使用
i
glob标志直接使用不区分大小写的匹配:

setopt extendedglob
[[ $str1 = (#i)$str2 ]] && echo "Match success"
[[ $str1 = (#i)match ]] && echo "Match success"

我遇到了这个很棒的博客/教程/随便什么。下面用例子详细解释了以下三种方法:

1。使用tr命令将图案转换为小写

opt=$( tr '[:upper:]' '[:lower:]' <<<"$1" )
case $opt in
        sql)
                echo "Running mysql backup using mysqldump tool..."
                ;;
        sync)
                echo "Running backup using rsync tool..."
                ;;
        tar)
                echo "Running tape backup using tar tool..."
                ;;
        *)
                echo "Other options"
                ;;
esac
3.打开nocasematch

opt=$1
shopt -s nocasematch
case $opt in
        sql)
                echo "Running mysql backup using mysqldump tool..."
                ;;
        sync)
                echo "Running backup using rsync tool..."
                ;;
        tar)
                echo "Running tape backup using tar tool..."
                ;;
        *)
                echo "Other option"
                ;;
esac

shopt -u nocasematch


对于任何使用
if
语句比较字符串的人,
shopt
方法要求使用双括号
[[]]
形式的条件语句,而不是单括号
[]
表单。另请参见:问题表明
==
用于比较两个字符串,但响应使用
大小写
语句演示了不区分大小写的比较。令人欣慰的是,
shopt
解决方案还支持使用
=
=~
和其他字符串比较运算符进行不区分大小写的比较rs.在比较完成后执行
shopt-u nocasematch
可能是明智的,以便恢复bash的默认设置。最好保存并恢复
nocasematch
设置。使用
SHELLNOCASEMATCH=`shopt-p nocasematch`
获取它,然后使用
shopt-s nocasematch
更改它,完成后,使用恢复它ode>$SHELLNOCASEMATCH
更好:
SHELLNOCASEMATCH=$(shopt-p nocasematch;true)
,因为如果未设置选项,
shopt-p
将以代码1退出,并且如果
set-e
有效,这可能会导致脚本中止。如果var2中有任何正则表达式特殊字符,则无法工作。这在性能方面比启动awk或任何其他进程要好得多。在bash中,可以使用declare-l或-u来执行t属性。至少是一个不暗示shopt选项的回复。因此,您可以比较两个字符串忽略大小写,并在同一测试中,比较两个其他大小写。Thank这是Bash 4中的新功能吗?至少在Bash 3.2.51(在OS X 10.9中使用)中,它不起作用-第一个
echo
语句的结果是:
-Bash:${var1,,}:错误的替换
这种不区分大小写的比较实现容易出现本地化问题(例如土耳其语I问题)。我不知道如何实现
shopt-s nocasematch
,但通常是这样的“语言级别”解决方案正确处理。@Ohad Schneider,让土耳其人担心土耳其语的本地化问题,我只需要一种快速有效的字符串匹配方法,这就需要Huuuuge marginboth的蛋糕
^
bash 4.4.20
中工作,但在
zsh 5.4.2
中都不工作(ubuntu 18.04)很好,因为
case
语句(包括ghostdog答案中的语句)总是会让我的皮肤蠕动。这只在Bash 4或更高版本(例如Mac OS X 10.11)中可用@d4Rk,这就是为什么我答案的第一句话说“只要你有Bash 4”。话虽如此,在撰写此评论时,Bash 4已经推出七年多了,而我自己的OS X安装已经有了差不多那么长的时间了。@很抱歉,我一开始没有注意到。我知道你可以在OS X上安装任何你想要的Bash,但默认值是3.2,而且我的脚本也必须在不同的Mac上运行,这不是真的lly对我来说是一个选项。@d4Rk这是可以理解的-如果你真的需要保证可移植性,我建议你坚持POSIX外壳标准,因为在某些情况下你根本不能保证找到任何版本的bash。这正是我想要的。应该更高=)我在基于alpine的docker-ized应用程序中使用了
tr
方法(通过
busybox
提供
sh
)。谢谢。如果fgrep-qix--“$str1”,最好使用

setopt extendedglob
[[ $str1 = (#i)$str2 ]] && echo "Match success"
[[ $str1 = (#i)match ]] && echo "Match success"
opt=$( tr '[:upper:]' '[:lower:]' <<<"$1" )
case $opt in
        sql)
                echo "Running mysql backup using mysqldump tool..."
                ;;
        sync)
                echo "Running backup using rsync tool..."
                ;;
        tar)
                echo "Running tape backup using tar tool..."
                ;;
        *)
                echo "Other options"
                ;;
esac
opt=$1
case $opt in
        [Ss][Qq][Ll])
                echo "Running mysql backup using mysqldump tool..."
                ;;
        [Ss][Yy][Nn][Cc])
                echo "Running backup using rsync tool..."
                ;;
        [Tt][Aa][Rr])
                echo "Running tape backup using tar tool..."
                ;;
        *)
                echo "Other option"
                ;;
esac
opt=$1
shopt -s nocasematch
case $opt in
        sql)
                echo "Running mysql backup using mysqldump tool..."
                ;;
        sync)
                echo "Running backup using rsync tool..."
                ;;
        tar)
                echo "Running tape backup using tar tool..."
                ;;
        *)
                echo "Other option"
                ;;
esac

shopt -u nocasematch