我正在尝试在新行分隔的字符串列表中匹配整个字符串。这是我的示例:
[hemanth.a@gateway ~]$ echo $snapshottableDirs
/user/hemanth.a/dummy1 /user/hemanth.a/dummy3
[hemanth.a@gateway ~]$ echo $snapshottableDirs | tr -s ' ' '\n'
/user/hemanth.a/dummy1
/user/hemanth.a/dummy3
[hemanth.a@gateway ~]$ echo $snapshottableDirs | tr -s ' ' '\n' | grep -w '/user/hemanth.a'
/user/hemanth.a/dummy1
/user/hemanth.a/dummy3
我的目标是仅在字符串列表中字符串/user/hemanth.a
作为一个整体单词(在新行中)存在时,才找到匹配项。但是,上面的命令还会返回包含/user/hemanth.a
的字符串。
这是一个示例方案。无法保证我要匹配的所有字符串都将采用/user/xxxxxx.x
的形式。理想情况下,如果列表中的整个单词都以换行形式存在,则我希望匹配确切的字符串。
任何帮助将不胜感激。谢谢。
答案 0 :(得分:3)
更新:这里使用fgrep -x '/user/hemanth.a'
可能是一个更好的解决方案,因为它避免了必须转义$
这样的字符以防止grep
解释为元字符。 fgrep
执行文字字符串匹配,而不是正则表达式匹配,并且-x
选项告诉它仅匹配整行。
示例:
> cat testfile.txt
foo
foobar
barfoo
barfoobaz
> fgrep foo testfile.txt
foo
foobar
barfoo
barfoobaz
> fgrep -x foo testfile.txt
foo
原始答案:
尝试在$
表达式的末尾添加grep
正则表达式元字符,如下所示:
echo $snapshottableDirs | tr -s ' ' '\n' | grep -w '/user/hemanth.a$'.
$
元字符与行尾匹配。
在进行此操作时,您可能还想使用^
元字符,该字符与行的开头相匹配,因此grep '/user/hemanth.a$'
不会偶然也与{{1 }}。
所以你会得到这个:
/user/foo/user/hemanth.a
编辑:您可能实际上并不希望在这里使用echo $snapshottableDirs | tr -s ' ' '\n' | grep '^/user/hemanth\.a$'.
,所以我将其从答案中删除了。
编辑2 :@U。 Windl提出了一个观点。正则表达式中的-w
字符是与 any 字符匹配的元字符,因此.
可能最终与您不期望的内容匹配,例如grep /user/hemanth.a
等等。或者更可能的是,它也将与行/user/hemanthxa
相匹配。要解决此问题,您需要转义/user/hemanth/a
字符。我已经更新了上面的.
行以反映这一点。
更新:针对您在注释中有关如何转义字符串以便可以在grep
正则表达式中使用它的评论...
是的,您可以转义字符串,以便可以在正则表达式中使用它。我将解释如何执行此操作,但是首先我应该说,在许多奇怪的边缘情况下,尝试转义用于正则表达式的字符串可能会变得非常复杂。例如,与grep
一起使用的转义字符串不一定与grep
,sed
,awk
,bash的perl
运算符甚至{{ 1}}。
最重要的是,如果您从单引号更改为双引号,则可能必须添加另一级转义,以便bash可以正确扩展您的字符串。
例如,如果您想使用=~
搜索文字字符串grep -e
,则必须转义'foo [bar]* baz$'
,{{1 }}和grep
个字符,得出正则表达式:
[
但是,如果由于某种原因您决定将该表达式作为双引号字符串传递给*
,则必须转义转义符。否则,bash会将其中一些解释为转义符。您可以通过以下方式查看此信息:
$
您可以看到bash将'foo \[bar]\* baz\$'
解释为代表字符grep
的转义序列,从而吞噬了echo "foo \[bar]\* baz\$"
foo \[bar]\* baz$
字符。这是因为通常在双引号字符串\$
中是一个特殊字符,它开始参数扩展。但由于$
和\
在双引号字符串中并不特殊,因此它单独保留了$
和\[
,因此它将反斜杠解释为文字\*
字符。为了使该表达式能够在双引号字符串中用作[
的参数,则必须转义最后一个反斜杠:
*
但是请注意,\
不能与grep
一起使用,因为# This command prints nothing, because bash expands `\$` to just `$`,
# which grep then interprets as an end-of-line anchor.
> echo 'foo [bar]* baz$' | grep "foo \[bar]\* baz\$"
# Escaping the last backslash causes bash to expand `\\$` to `\$`,
# which grep then interprets as matching a literal $ character
> echo 'foo [bar]* baz$' | grep "foo \[bar]\* baz\\$"
foo [bar]* baz$
使用不同的正则表达式语法,转义"foo \[bar]\* baz \\$"
会导致它{要成为一个元字符,而在sed
中,您必须对其进行转义以防止将其解释为元字符。
同样,是的,您可以转义文字字符串以用作sed
正则表达式。但是,如果您需要匹配包含需要转义的字符的文字字符串,那么事实证明,还有一种更好的方法:[
。
grep
命令实际上只是grep
的简写,其中fgrep
告诉fgrep
匹配“固定字符串”而不是正则表达式。例如:
grep -F
之所以起作用,是因为-F
不了解或不关心正则表达式。它只是在寻找确切的文字字符串grep
。但是,由于> echo '[(*\^]$' | fgrep '[(*\^]$'
[(*\^]$
将在子字符串上匹配,因此这种情况使您回到第一个平方。
fgrep
很高兴,有一个解决方法,事实证明,考虑到您的特定需求,这可能是比我最初的回答更好的方法。 '[(*\^]$'
的{{1}}选项告诉它仅匹配整行。请注意,fgrep
并非特定于> echo '/users/hemanth/dummy' | fgrep '/users/hemanth'
/users/hemanth/dummy
(因为-x
实际上只是fgrep
)。例如:
-x
这等效于转义fgrep
的正则表达式,几乎可以肯定比我以前的将正则表达式包含在fgrep
和grep -F
中的答案更好。
现在,如所承诺的那样,以防万一,如果您想走这条路,这是您转义固定字符串以用作> echo '/users/hemanth/dummy' | fgrep -x '/users/hemanth' # prints nothing
正则表达式的方法:
grep
同样,出于上述原因,我不建议您使用这种方法,尤其是当^
存在时。
答案 1 :(得分:1)
在filePath.replacingOccurrences(of: "file://", with: "")
中阅读“锚定”:
man grep
还请注意, Anchoring
The caret ^ and the dollar sign $ are meta-characters that respectively
match the empty string at the beginning and end of a line.
与任何字符都匹配(来自所述手册页):
.