如何比较Bash中的字符串

Eri*_*pir 897 string bash

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

Joh*_*lla 1288

在if语句中使用变量

if [ "$x" = "valid" ]; then
  echo "x has the value 'valid'"
fi
Run Code Online (Sandbox Code Playgroud)

如果您想在不匹配时执行某些操作,请替换=!=.您可以在各自的文档中阅读有关字符串操作算术运算的更多信息.

为什么我们使用报价$x

你想要引号$x,因为如果它是空的,你的bash脚本遇到语法错误,如下所示:

if [ = "valid" ]; then
Run Code Online (Sandbox Code Playgroud)

非标准使用==运营商

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

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

if [[ "$x" == "valid" ]]; then
Run Code Online (Sandbox Code Playgroud)

或使用第二种情况:

if [ "$x" = "valid" ]; then
Run Code Online (Sandbox Code Playgroud)

  • 这些空间是必需的. (70认同)
  • 值得注意的是你不能使用`[$ x -eq"valid"]`.`-eq`是整数的比较运算符,而不是字符串. (65认同)
  • 这与[意外的操作员错误](http://stackoverflow.com/q/2011160/95735)中给出的接受答案有何关系?当使用`["$ 1"=="on"]时,我得到了同样的错误.将此更改为["$ 1"="on"]解决了问题. (11认同)
  • 不应该是代码中的`["x $ yes"=="xyes"]` (8认同)
  • @JohnFeminella在用bash脚本编写时,它应该有一个`=`而不是两个. (5认同)
  • @user13107:不准确。对于字符串比较,“==”与“=”相同。(此外,您总是需要使用“==”进行数字比较。) (2认同)
  • @user13107 那么你可能使用的是 `sh`,而不是 `bash`。这是一个关于“bash”的问题。 (2认同)
  • @Alex,在哪种情况下(如果有的话),我需要使用模式`[[“ x $ yes” ==“ xyes”]`,即在变量和字符串文字前都加上`x`吗?那是古老的遗迹吗?还是在某些情况下真的需要吗? (2认同)

Mar*_*rko 132

或者,如果您不需要else子句:

[ "$x" == "valid" ] && echo "x has the value 'valid'"
Run Code Online (Sandbox Code Playgroud)

  • 如果你确实需要一个else子句并想制作一个疯狂的单行:["$ x"=="valid"] && echo"valid"|| 回声"无效" (68认同)
  • @MattWhite:这通常是一个坏主意,因为`echo`可能会失败. (10认同)
  • 在 POSIX sh 中,用 == 代替 = 是未定义的。[[SC2039](https://github.com/koalaman/shellcheck/wiki/SC2039)] (5认同)
  • @ 12431234123412341234123` {echo invalid && false; ``比`(echo invalid && false)`更有效,因为它避免支付不必要的子shell. (4认同)
  • @gniourf_gniourf,没问题,请使用`["$ X"=="有效"] || (echo invalid && false)&& echo"valid"`. (3认同)

Gur*_*uru 71

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
Run Code Online (Sandbox Code Playgroud)

笔记:

  1. 之间的空间if[]是重要的
  2. >并且<是重定向操作符因此与逃避它\>,并\<分别用于字符串.

  • 感谢字符串字母顺序比较 (5认同)

Jef*_*rts 59

要使用通配符比较字符串

if [[ "$stringA" == *$stringB* ]]; then
  # Do something here
else
  # Do Something here
fi
Run Code Online (Sandbox Code Playgroud)

  • 重要的是通配符只能在右侧使用!还要注意通配符周围缺少的"".(顺便说一下:通配符为+1!) (12认同)
  • 必须引用扩展`$ stringB`**(顺便提一下,左手边不需要引用):`if [[$ stringA =*"$ stringB"*]]; then`. (6认同)

Vol*_*gel 33

我不得不在一点上不同意其中一条评论:

[ "$x" == "valid" ] && echo "valid" || echo "invalid"
Run Code Online (Sandbox Code Playgroud)

不,这不是一个疯狂的oneliner

它只是看起来像一个,嗯,没有经验......

它在某种程度上使用常见的模式作为语言;

在你学会了这门语言之后.

实际上,阅读很好

它是一个简单的逻辑表达式,有一个特殊部分:逻辑运算符的惰性求值.

[ "$x" == "valid" ] && echo "valid" || echo "invalid"
Run Code Online (Sandbox Code Playgroud)

每个部分都是一个逻辑表达; 第一个可能是真或假,另外两个总是如此.

(
[ "$x" == "valid" ] 
&&
echo "valid"
)
||
echo "invalid"
Run Code Online (Sandbox Code Playgroud)

现在,在评估时,检查第一个.如果是假的,比逻辑的第二个操作数 &&之后是不相关的.第一个不是真的,所以它不可能是第一个和第二个是真的,无论如何.
现在,在这种情况下是逻辑的第一面 ||假,但如果另一面 - 第三部分 - 是真的,则可能是真的.

所以第三部分将被评估 - 主要是将信息写成副作用.(它的结果0为true,我们这里不使用)

其他情况类似,但更简单 - 而且 - 我保证!是 - 可以 - 易于阅读!
(我没有,但我认为作为一名灰白胡子的UNIX老手对此有很大的帮助.)

  • `... && ... || ......`通常都不赞成(对不起greyyard Unix老手,你一直都错了),因为它在语义上不等同于`if ... then ... else ...`.别担心,[这是一个常见的陷阱](http://mywiki.wooledge.org/BashPitfalls#cmd1_.26.26_cmd2_.7C.7C_cmd3). (15认同)
  • @gniourf_gniourf OP没有错 - 它们也不像你建议的那样无知.`... && ... || ...`是一个完全有效的模式和一个常见的bash成语.使用它确实规定了先前的知识(如果观众中有初学者,可能会记住这些知识),但OP有头发证明他们知道如何避免打开井盖. (6认同)
  • @ebpa如果&amp;&amp;后面的语句返回false值,将执行||后面的语句怎么办??如果是这样,那是错误的,也许是gniourf在暗示什么 (3认同)
  • 我认为回声只是一个例子.&&后面的语句可能仍会返回非零值 (3认同)
  • @gniourf_gniourf +1发布了Bash Pitfalls的链接!很有用! (2认同)

gho*_*g74 20

你也可以使用用例/ esac

case "$string" in
 "$pattern" ) echo "found";;
esac
Run Code Online (Sandbox Code Playgroud)


小智 15

以下脚本逐行从名为"testonthis"的文件中读取,然后将每行与一个简单的字符串,一个带有特殊字符的字符串和一个正则表达式(如果它不匹配)进行比较,那么脚本将打印该行而不是.

bash中的空间非常重要.所以下面的工作

[ "$LINE" != "table_name" ] 
Run Code Online (Sandbox Code Playgroud)

但是以下不会:

["$LINE" != "table_name"] 
Run Code Online (Sandbox Code Playgroud)

所以请按原样使用:

cat testonthis | while read LINE
do
if [ "$LINE" != "table_name" ] && [ "$LINE" != "--------------------------------" ] && [[ "$LINE" =~ [^[:space:]] ]] && [[ "$LINE" != SQL* ]]; then
echo $LINE
fi
done
Run Code Online (Sandbox Code Playgroud)


ste*_*cat 11

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

if [[ "${ACTION,,}" =~ ^(start|stop)$ ]]; then
  echo "valid action"
fi
Run Code Online (Sandbox Code Playgroud)

请注意,我$ACTION使用双逗号来小写变量.另请注意,这对于太老的bash版本不起作用.


Mik*_*e Q 8

Bash4 +示例.注意:当单词包含空格等时,不使用引号会导致问题.总是引用bash IMO.

以下是BASH4 +的一些示例:

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

    if [[ "${str,,}" == *"yes"* ]] ;then
Run Code Online (Sandbox Code Playgroud)

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

    if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then
Run Code Online (Sandbox Code Playgroud)

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

     if [[ "${str}" == *"yes"* ]] ;then
Run Code Online (Sandbox Code Playgroud)

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

     if [[ "${str}" =~ "yes" ]] ;then
Run Code Online (Sandbox Code Playgroud)

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

     if [[ "${str}" == "yes" ]] ;then
Run Code Online (Sandbox Code Playgroud)

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

     if [[ "${str,,}" == "yes" ]] ;then
Run Code Online (Sandbox Code Playgroud)

例7,完全匹配:

     if [ "$a" = "$b" ] ;then
Run Code Online (Sandbox Code Playgroud)

请享用.