我有一个grep
处理字符串的命令
test-test test
我希望该命令仅向我显示突出显示的“独立”一词test
,而不是test-test
.
然而,当我跑步时
echo "test-test test" | grep -w "test"
我突出test
显示了所有发生的情况。
是否可以将匹配限制为仅孤立出现test
?
答案1
所有test
出现的内容都以粗体显示,因为-w
单词是由非单词字符分隔的单词字符序列,单词字符是字母数字和下划线。-
不是单词字符。
在 中testing-test+test2;test_3;untested
,只有第二个test
匹配项匹配,因为这是唯一一个前面或后面都没有单词字符的匹配项。
如果您想匹配以空格分隔的单词,则必须指定这些环视四周手动断言,并且您需要与 perl 兼容的正则表达式来实现并非所有grep
实现都支持的功能。由于您似乎有一个grep='grep --color
别名,如果您grep
支持--color
,那么它也有可能支持-P
/-X perl
选项,然后您可以执行以下操作:
grep --color -P '(?<!\S)test(?!\S)'
(?<!...)
并(?!...)
分别是Perl 正则表达式中的负向后看和向前看断言运算符。\S
,就像 POSIX 的[^[:space:]]
匹配和不属于空白的字符。这就是说:“test
只要它前面或后面都没有非空白字符,就匹配”。
答案2
使用 Perl 正则表达式(在带有-P
标志的 GNU grep 中受支持),您可以使用负向后查找和向前查找来断言 的匹配test
不与 相邻-
:
echo "test-test test" | grep -P '(?<!-)test(?!-)'
这输出
测试一下测试
答案3
使用扩展的正则表达式,你可以像这样实现它
grep -E "(^| )test( |$)"
需要注意的是,这实际上会突出显示任何前导或训练空间,但您不会看到它,因为它不是可打印的字符。
答案4
使用珀尔:
~$ echo "test-test test\ntest\n\n" | perl -lpe 's/(?<!\S)(test)(?!\S)/**$1**/g;'
test-test **test**
**test**
使用乐:
~$ echo "test-test test\ntest\n\n" | raku -pe 's:g/ <!after \S > (test) <!before \S > /**$0**/;'
test-test **test**
**test**
[特别感谢@StéphaneChazelas 在他的grep
回答中对 Perl 风格的 Lookarounds 的阐述]。
如果你想要类似于突出显示的东西,这里有一个简单的想法珀尔蒙克斯。grep
使用 Perl/Raku 并用星号包围匹配项,而不是的颜色选项**
。
after
Raku 注:Lookbehinds在 Raku 中拼写?
为积极和消极,而 Lookaheads在 Raku 中!
拼写为积极和消极。所以你可以直接阅读上面的 Raku 代码:before
?
!
“全局替换单词“test”的任何匹配项,而不after
是非空白字符,也不是非before
空白字符......”。
https://perldoc.perl.org/perlre#Lookaround-Assertions
https://docs.raku.org/language/regexes#Lookahead_assertions
https://docs.raku.org/language/regexes#Lookbehind_assertions