如何比较bash中的字符串

How to compare strings in Bash

如何将变量与字符串进行比较(如果匹配,则执行某些操作)?


在if语句中使用变量

1
2
3
if ["$x" ="valid" ]; then
  echo"x has the value 'valid'"
fi

如果你想在它们不匹配的时候做点什么,用!=替换=。您可以在各自的文档中了解更多关于字符串操作和算术操作的信息。

我们为什么要在$x周围使用报价?

您需要在$x周围加引号,因为如果它是空的,那么您的bash脚本会遇到如下语法错误:

1
if [ ="valid" ]; then

==运算符的非标准使用

注意,bash允许==用于与[相等,但这不是标准。

使用第一种情况,其中$x周围的引号是可选的:

1
if [["$x" =="valid" ]]; then

或者使用第二种情况:

1
if ["$x" ="valid" ]; then


或者,如果不需要其他条款:

1
["$x" =="valid" ] && echo"x has the value 'valid'"


要比较字符串和通配符,请使用

1
2
3
4
5
if [["$stringA" == *$stringB* ]]; then
  # Do something here
else
  # Do Something here
fi


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
a="abc"
b="def"

# Equality Comparison
if ["$a" =="$b" ]; then
    echo"Strings match"
else
    echo"Strings don't match"
fi

# Lexicographic (greater than, less than) comparison.
if ["$a" \<"$b" ]; then
    echo"$a is lexicographically smaller then $b"
elif ["$a" \>"$b" ]; then
    echo"$b is lexicographically smaller than $a"
else
    echo"Strings are equal"
fi

笔记:

  • if[]之间的空间很重要。
  • ><是重定向运算符,因此分别用\>\<对字符串进行转义。

  • 我必须在一点上不同意其中一条评论:

    1
    ["$x" =="valid" ] && echo"valid" || echo"invalid"

    不,那不是一条疯狂的单行线

    只是它看起来像一个,嗯,不起眼的…

    在某种程度上,它使用共同的模式作为一种语言;

    在你学会了语言之后。

    事实上,读起来很好

    它是一个简单的逻辑表达式,有一个特殊的部分:逻辑运算符的延迟计算。

    1
    ["$x" =="valid" ] && echo"valid" || echo"invalid"

    每一部分都是一个逻辑表达式;第一部分可能是对的,也可能是错的,另外两部分总是对的。

    1
    2
    3
    4
    5
    6
    7
    (
    ["$x" =="valid" ]
    &&
    echo"valid"
    )
    ||
    echo"invalid"

    现在,当它被评估时,第一个被检查。如果为假,则大于逻辑的第二个操作数,且后面的&&不相关。第一个不是真的,所以它不能是第一个,第二个也是真的。现在,在这种情况下,逻辑的第一个方面或||错误,但如果另一个方面(第三部分)是正确的,则可能是正确的。

    因此,第三部分将被评估——主要是作为副作用编写消息。(其结果为:0为真,我们在这里不使用)

    其他的情况是相似的,但更简单——我保证!容易阅读!(我没有,但我认为作为一名留着灰胡子的Unix老兵,这对我有很大帮助。)


    您还可以使用用例/ESAC

    1
    2
    3
    case"$string" in
    "$pattern" ) echo"found";;
    esac


    下面的脚本逐行从名为"testonhis"的文件中读取,然后将每一行与一个简单字符串、一个带有特殊字符的字符串和一个正则表达式进行比较。如果不匹配,则脚本将打印行"o/w not"。

    bash中的空间非常重要。所以下面就行了

    1
    ["$LINE" !="table_name" ]

    但以下不会:

    1
    ["$LINE" !="table_name"]

    所以请按原样使用:

    1
    2
    3
    4
    5
    6
    cat testonthis | while read LINE
    do
    if ["$LINE" !="table_name" ] && ["$LINE" !="--------------------------------" ] && [["$LINE" =~ [^[:space:]] ]] && [["$LINE" != SQL* ]]; then
    echo $LINE
    fi
    done


    如果输入只有几个有效的条目,我可能会使用regexp匹配。例如,只有"开始"和"停止"才是有效的操作。

    1
    2
    3
    if [["${ACTION,,}" =~ ^(start|stop)$ ]]; then
      echo"valid action"
    fi

    请注意,我使用双逗号将变量$ACTION小写。还要注意,这在太老的bash版本上不起作用。


    bash4+示例。注意:不使用引号会导致单词包含空格等问题。总是引用bash imo的话。

    下面是一些示例bash4+:

    示例1,检查字符串中的"是"(不区分大小写):

    1
        if [["${str,,}" == *"yes"* ]] ;then

    示例2,检查字符串中的"是"(不区分大小写):

    1
        if [["$(echo"$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then

    示例3,检查字符串中的"是"(区分大小写):

    1
         if [["${str}" == *"yes"* ]] ;then

    示例4,检查字符串中的"是"(区分大小写):

    1
         if [["${str}" =~"yes" ]] ;then

    示例5,完全匹配(区分大小写):

    1
         if [["${str}" =="yes" ]] ;then

    示例6,完全匹配(不区分大小写):

    1
         if [["${str,,}" =="yes" ]] ;then

    例7,完全匹配:

    1
         if ["$a" ="$b" ] ;then

    享受。


    我这样做是为了与bash、dash(sh)兼容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    testOutput="my test"
    pattern="my"

    case $testOutput in (*"$pattern"*)
        echo"if there is a match"
        exit 1
        ;;
    (*)
       ! echo there is no coincidence!
    ;;esac