bash 使用 grep 比较两个字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22631415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:00:35  来源:igfitidea点击:

compare two strings using grep

linuxbashshell

提问by Asish Pati

echo "abc-vcu def" | grep -w "abc.vcu" 
echo $?

The output of the above line is 0. But abc-vcu!= abc.vcuand def!= abc.vcu. So it should return 1.

上面一行的输出是0. 但是abc-vcu!=abc.vcudef!= abc.vcu。所以它应该返回1

Command is returning true because it is assuming .and -are same. How to do exact comparing?

命令返回 true 因为它假设.并且-是相同的。如何进行精确比较?

回答by Gennadiy Litvinyuk

In grep .means any character(regular expression syntax)

在 grep 中.表示任何字符(正则表达式语法)

If you need to match .try \.

如果你需要匹配.试试\.

echo "abc-vcu def" | grep -w "abc\.vcu"
echo $?

回答by Adaephon

Instead of using grepyou could let bashdo the work, especially if you intend to use variables anyway:

grep您可以让我们bash完成工作,而不是使用,特别是如果您打算使用变量:

string1='abc-vcu def'
string2='abc.vcu'
[[ ! ${string1/*${string2}*/} ]]
echo $?

[[ expression ]]returns 0or 1depending on the evaluation of expression.

[[ expression ]]返回01取决于 的评估expression

!is a logical not.

!合乎逻辑的不

${parameter/pattern/string}replaces the first occurence of patternin parameterby string, where patternis expanded just as in pathname expansions. For the above case that means that if $string2appears anywhere in $string1, $string1is completely replaced by ''(an empty string), which is a logical false.

${parameter/pattern/string}替换第一次出现patternparameterstring其中pattern的,就像路径扩展扩展。对于上述情况,这意味着 if$string2出现在 中的任何地方$string1$string1完全被''(空字符串)替换,这是一个逻辑假

回答by tripleee

What you are attempting is better achieved with a simple string comparison.

通过简单的字符串比较可以更好地实现您的尝试。

if [[ "abc-vcu def" == *"abc.vcu"* ]]; then
    echo "String B contained in String A"
else
    echo "No containment"
fi

Notice also how this avoids the antipattern of examining $?. Just to elaborate, anything that looks like

还要注意这如何避免检查的反模式$?。只是详细说明,任何看起来像

command
if [ $? == 0 ]; then ...

is better written as

最好写成

if command; then ...

Tangentially, if you really do want or have to use grep, there are some options you need to understand. grepmatches regular expressions, not just strings. There is a separate option to change the search expression into a string, namely -F(traditionally available as a separate command fgrep):

切线地讲,如果您确实想要或必须使用grep,则需要了解一些选项。 grep匹配正则表达式,而不仅仅是字符串。有一个单独的选项可以将搜索表达式更改为字符串,即-F(传统上作为单独的命令可用fgrep):

echo moo | grep m.o     # true
echo moo | grep -F m.o  # false

Just for completeness, note also that greplooks for a match anywhere in the input. So echo moo | grep ois true. If you really want to look for an exact match, you need the -xoption (or change the expression you are grepping for):

只是为了完整性,还要注意grep在输入中的任何地方寻找匹配。所以,echo moo | grep o是真实的。如果您真的想查找完全匹配,则需要该-x选项(或更改您要查找的表达式):

echo moo | grep -x moo
echo moo | grep '^moo$'

Like @Kent remarks, grepwill print any matching lines by default, which you probably don't want here -- you are only running grepto see if there is a match. So you need the -qflag as well. To summarize,

就像@Kent 的评论一样,grep默认情况下会打印任何匹配的行,您可能不希望在此处打印 - 您只是在运行grep以查看是否存在匹配项。所以你也需要-q旗帜。总结一下,

echo "abc-vcu def" | grep -Fxwq "abc.vcu"

Finally, you should probably also be aware of case:

最后,您可能还应该知道case

case "abc-vcu def" in *"abc.vcu"*) echo true;; *) echo false;; esac

Unlike the [[Bash-only test, caseis portable all the way back to the original Bourne shell.

[[Bash-only 测试不同,它case可以一直移植到原始的 Bourne shell。

回答by Sergey Fedorov

If you do want to use grepin this case, use it as follows:

如果您确实想grep在这种情况下使用,请按如下方式使用它:

echo "abc-vcu def" | grep -F -w "abc.vcu"

man grepsays that with -Fgrep must

man grep-Fgrep 必须

Interpret PATTERN as a list of fixed strings

将 PATTERN 解释为固定字符串列表

This fixes the problem that .is recognized as 'any symbol' pattern.

这解决了.被识别为“任何符号”模式的问题。