如何在bash中比较if条件中的两个字符串

时间:2022-08-29 12:02:38
s="STP=20"

if [[ "$x" == *"$s"* ]]

The if condition is always false; why?

if条件总是假的;为什么?

5 个解决方案

#1


3  

Try this: http://tldp.org/LDP/abs/html/comparison-ops.html

试试这个:http://tldp.org/LDP/abs/html/comparison-ops.html

string comparison

=

  is equal to

  if [ "$a" = "$b" ]

#2


5  

There is a difference in testing for equality between [ ... ] and [[ ... ]].

[...]和[[...]]之间的平等测试存在差异。

The [ ... ] is an alias to the test command:

[...]是测试命令的别名:

STRING1 = STRING2 the strings are equal

STRING1 = STRING2字符串相等

However, when using [[ ... ]]

但是,使用[[...]]时

When the == and != operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below under Pattern Matching. If the shell option nocasematch is enabled, the match is performed without regard to the case of alphabetic characters. The return value is 0 if the string matches (==) or does not match (!=) the pattern, and 1 otherwise. Any part of the pattern may be quoted to force it to be matched as a string.

当使用==和!=运算符时,运算符右侧的字符串被视为模式,并根据模式匹配下面描述的规则进行匹配。如果启用了shell选项nocasematch,则执行匹配而不考虑字母字符的情况。如果字符串匹配(==)或与模式不匹配(!=),则返回值为0,否则返回1。可以引用模式的任何部分以强制它作为字符串匹配。

The same seems to be true with just the = sign:

只有=符号似乎也是如此:

$ foo=bar
$ if [[ $foo = *ar ]]
> then
>     echo "These patterns match"
> else
>     echo "These two strings aren't equal"
> fi
These patterns match

Note the difference:

注意区别:

$ foo=bar
> if [ $foo = *ar ]
> then
>     echo "These patterns match"
> else
>     echo "These two strings aren't equal"
> fi
These two strings aren't equal

However, there are a few traps with the [ $f00 = *ar ] syntax. This is the same as:

但是,[$ f00 = * ar]语法有一些陷阱。这与:

test $foo = *ar

Which means the shell will interpolate glob expressions and variables before executing the statement. If $foo is empty, the command will become equivalent to:

这意味着shell将在执行语句之前插入glob表达式和变量。如果$ foo为空,则该命令将等效于:

test = *ar  # or [ = *ar ]

Since the = isn't a valid comparison operator in test, you'll get an error like:

由于=在测试中不是有效的比较运算符,因此会出现如下错误:

bash: [: =: unary operator expected

Which means the [ was expecting a parameter found in the test manpage.

这意味着[期待在测试手册页中找到参数。

And, if I happen to have a file bar in my directory, the shell will replace *ar with all files that match that pattern (in this case bar), so the command will become:

而且,如果我的目录中碰巧有一个文件栏,那么shell会将* ar替换为与该模式匹配的所有文件(在本例中为bar),因此该命令将变为:

[ $foo = bar ]

which IS true.

这是真的。

To get around the various issues with [ ... ], you should always put quotes around the parameters. This will prevent the shell from interpolating globs and will help with variables that have no values:

要解决[...]的各种问题,您应该始终在参数周围加上引号。这将阻止shell插入globs并帮助处理没有值的变量:

[ "$foo" = "*ar" ]

This will test whether the variable $foo is equal to the string *ar. It will work even if $foo is empty because the quotation marks will force an empty string comparison. The quotes around *ar will prevent the shell from interpolating the glob. This is a true equality.

这将测试变量$ foo是否等于字符串* ar。即使$ foo为空也会有效,因为引号会强制进行空字符串比较。 * ar周围的引号将阻止shell插入glob。这是一个真正的平等。

Of course, it just so happens that if you use quotation marks when using [[ ... ]], you'll force a string match too:

当然,如果你在使用[[...]]时使用引号,你也会强制进行字符串匹配:

foo=bar
if [[ $foo == "*ar" ]]
then
    echo "This is a pattern match"
else
    echo "These strings don't match"
fi

So, in the end, if you want to test for string equality, you can use either [ ... ] or [[ ... ]], but you must quote your parameters. If you want to do glob pattern matching, you must leave off the quotes, and use [[ ... ]].

因此,最后,如果要测试字符串相等性,可以使用[...]或[[...]],但必须引用参数。如果要进行glob模式匹配,则必须不使用引号,并使用[[...]]。

#3


1  

To compare two strings in variables x and y for equality, use

要比较变量x和y中的两个字符串是否相等,请使用

if test "$x" = "$y"; then
   printf '%s\n' "equal"
else
   printf '%s\n' "not equal"
fi

To test whether x appears somewhere in y, use

要测试x是否出现在y的某个位置,请使用

case $y in
   (*"$x"*)
      printf '%s\n' "$y contains $x"
      ;;
   (*)
      printf '%s\n' "$y does not contain $x"
      ;;
esac

Note that these constructs are portable to any POSIX shell, not just bash. The [[ ]] construct for tests is not (yet) a standard shell feature.

请注意,这些构造可以移植到任何POSIX shell,而不仅仅是bash。测试的[[]]结构不是(还)标准的shell功能。

#4


0  

I do not know where you came up with the *, but you were real close:

我不知道你在哪里提出*,但你真的很亲近:

s="STP=20"
if [[ "STP=20" == "$s" ]]; then
    echo "It worked!"
fi

#5


-1  

You need to escape = using \ in the string s="STP=20"

你需要在字符串s =“STP = 20”中转义=使用\

s="STP\=20"

if [[ "STP\=20" == "$s" ]]; then echo Hi; else echo Bye; fi

#1


3  

Try this: http://tldp.org/LDP/abs/html/comparison-ops.html

试试这个:http://tldp.org/LDP/abs/html/comparison-ops.html

string comparison

=

  is equal to

  if [ "$a" = "$b" ]

#2


5  

There is a difference in testing for equality between [ ... ] and [[ ... ]].

[...]和[[...]]之间的平等测试存在差异。

The [ ... ] is an alias to the test command:

[...]是测试命令的别名:

STRING1 = STRING2 the strings are equal

STRING1 = STRING2字符串相等

However, when using [[ ... ]]

但是,使用[[...]]时

When the == and != operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below under Pattern Matching. If the shell option nocasematch is enabled, the match is performed without regard to the case of alphabetic characters. The return value is 0 if the string matches (==) or does not match (!=) the pattern, and 1 otherwise. Any part of the pattern may be quoted to force it to be matched as a string.

当使用==和!=运算符时,运算符右侧的字符串被视为模式,并根据模式匹配下面描述的规则进行匹配。如果启用了shell选项nocasematch,则执行匹配而不考虑字母字符的情况。如果字符串匹配(==)或与模式不匹配(!=),则返回值为0,否则返回1。可以引用模式的任何部分以强制它作为字符串匹配。

The same seems to be true with just the = sign:

只有=符号似乎也是如此:

$ foo=bar
$ if [[ $foo = *ar ]]
> then
>     echo "These patterns match"
> else
>     echo "These two strings aren't equal"
> fi
These patterns match

Note the difference:

注意区别:

$ foo=bar
> if [ $foo = *ar ]
> then
>     echo "These patterns match"
> else
>     echo "These two strings aren't equal"
> fi
These two strings aren't equal

However, there are a few traps with the [ $f00 = *ar ] syntax. This is the same as:

但是,[$ f00 = * ar]语法有一些陷阱。这与:

test $foo = *ar

Which means the shell will interpolate glob expressions and variables before executing the statement. If $foo is empty, the command will become equivalent to:

这意味着shell将在执行语句之前插入glob表达式和变量。如果$ foo为空,则该命令将等效于:

test = *ar  # or [ = *ar ]

Since the = isn't a valid comparison operator in test, you'll get an error like:

由于=在测试中不是有效的比较运算符,因此会出现如下错误:

bash: [: =: unary operator expected

Which means the [ was expecting a parameter found in the test manpage.

这意味着[期待在测试手册页中找到参数。

And, if I happen to have a file bar in my directory, the shell will replace *ar with all files that match that pattern (in this case bar), so the command will become:

而且,如果我的目录中碰巧有一个文件栏,那么shell会将* ar替换为与该模式匹配的所有文件(在本例中为bar),因此该命令将变为:

[ $foo = bar ]

which IS true.

这是真的。

To get around the various issues with [ ... ], you should always put quotes around the parameters. This will prevent the shell from interpolating globs and will help with variables that have no values:

要解决[...]的各种问题,您应该始终在参数周围加上引号。这将阻止shell插入globs并帮助处理没有值的变量:

[ "$foo" = "*ar" ]

This will test whether the variable $foo is equal to the string *ar. It will work even if $foo is empty because the quotation marks will force an empty string comparison. The quotes around *ar will prevent the shell from interpolating the glob. This is a true equality.

这将测试变量$ foo是否等于字符串* ar。即使$ foo为空也会有效,因为引号会强制进行空字符串比较。 * ar周围的引号将阻止shell插入glob。这是一个真正的平等。

Of course, it just so happens that if you use quotation marks when using [[ ... ]], you'll force a string match too:

当然,如果你在使用[[...]]时使用引号,你也会强制进行字符串匹配:

foo=bar
if [[ $foo == "*ar" ]]
then
    echo "This is a pattern match"
else
    echo "These strings don't match"
fi

So, in the end, if you want to test for string equality, you can use either [ ... ] or [[ ... ]], but you must quote your parameters. If you want to do glob pattern matching, you must leave off the quotes, and use [[ ... ]].

因此,最后,如果要测试字符串相等性,可以使用[...]或[[...]],但必须引用参数。如果要进行glob模式匹配,则必须不使用引号,并使用[[...]]。

#3


1  

To compare two strings in variables x and y for equality, use

要比较变量x和y中的两个字符串是否相等,请使用

if test "$x" = "$y"; then
   printf '%s\n' "equal"
else
   printf '%s\n' "not equal"
fi

To test whether x appears somewhere in y, use

要测试x是否出现在y的某个位置,请使用

case $y in
   (*"$x"*)
      printf '%s\n' "$y contains $x"
      ;;
   (*)
      printf '%s\n' "$y does not contain $x"
      ;;
esac

Note that these constructs are portable to any POSIX shell, not just bash. The [[ ]] construct for tests is not (yet) a standard shell feature.

请注意,这些构造可以移植到任何POSIX shell,而不仅仅是bash。测试的[[]]结构不是(还)标准的shell功能。

#4


0  

I do not know where you came up with the *, but you were real close:

我不知道你在哪里提出*,但你真的很亲近:

s="STP=20"
if [[ "STP=20" == "$s" ]]; then
    echo "It worked!"
fi

#5


-1  

You need to escape = using \ in the string s="STP=20"

你需要在字符串s =“STP = 20”中转义=使用\

s="STP\=20"

if [[ "STP\=20" == "$s" ]]; then echo Hi; else echo Bye; fi