avi*_*iro 5 grep regular-expression
我试图理解为什么grep -w(GNU 实现的版本 3.1)仅匹配一行中特定模式的第一次出现。
这是一个例子。我希望它会匹配n1,n2和n3,但它只匹配第一个。
$ echo 'n1=1 n2=2 n3=3' | grep -ow "n[0-9]=*"
n1
Run Code Online (Sandbox Code Playgroud)
或者,如果我告诉它仅匹配n2或n3,它再次匹配第一个,并忽略n3。
$ echo 'n1=1 n2=2 n3=3' | grep -ow "n[23]=*"
n2
Run Code Online (Sandbox Code Playgroud)
我在这里缺少什么?对于这种行为有任何解释吗,或者这是 grep 中的某种错误?
这个想法是匹配:
n[0-9]前面和后面都是非单词字符。n[0-9]任意数量的=字符,以非单词字符结尾的子字符串。例如,如果字符串是n1=1 n2=== n3=3 n4== n5,则预期结果应该是:
n1
n2===
n3
n4==
n5
Run Code Online (Sandbox Code Playgroud)
澄清:我知道目标可以通过 实现grep -ow -e 'n[0-9]' -e "n[0-9]=*",但这不是重点。该问题的目的是了解如何grep工作。
如果我添加n<num>=到行中的不同位置(等号后没有后续单词字符),它也会匹配这些字符,但它会再次忽略n3=3.
$ echo 'n1=1 n2= n3=3 n4=' | grep -ow "n[0-9]=*"
n1
n2=
n4=
Run Code Online (Sandbox Code Playgroud)
我发现的最后一件事是,如果我添加-P将模式解释为与 Perl 兼容的正则表达式,它似乎不会保留-w子字符串“必须位于行尾或后面”的描述由非单词构成字符",因为n1=即使它后面跟着字符1,它也是匹配的,字符 1 是单词构成字符(“字母、数字和下划线”)。
$ echo 'n1=1 n2= n3=3 n4=' | grep -owP "n[0-9]=*"
n1=
n2
n3=
n4
Run Code Online (Sandbox Code Playgroud)
所以看起来是在子字符串末尾grep -wP搜索单词边界而不是非单词组成字符。它似乎相当于:
$ echo 'n1=1 n2= n3=3 n4=' | grep -o "\bn[0-9]=*\b"
n1=
n2
n3=
n4
Run Code Online (Sandbox Code Playgroud)
接得好。这似乎确实是一个错误grep (用 3.4 和 3.7 测试GNU grep):
grep -ow "n[0-9]=*"
grep -Eow "n[0-9]=*"
Run Code Online (Sandbox Code Playgroud)
仅返回第一个匹配项(或者可能只匹配第一个匹配项),
而...
grep -Pow "n[0-9]=*"
Run Code Online (Sandbox Code Playgroud)
...按预期返回所有匹配项。
要报告错误GNU grep,请检查此处。
但是,我无法确认您的观察结果,即-P[...] 似乎没有保留-w说明,对我来说(GNU grep 3.4 和 3.7),该命令按预期输出:
$ echo 'n1=1 n2= n3=3 n4=' | grep -owP "n[0-9]=*"
n1
n2=
n3
n4=
Run Code Online (Sandbox Code Playgroud)