我一直在广泛使用grep -w
,但最近我发现它并没有解决我的问题。
假设我有一个包含以下内容的文件:
$ cat Log.txt
aaa xxx zzz
bbb xxx aa
cccaaa yy aa
scn-aaa
我想过滤所有单词“aaa”完全匹配的行。这意味着不应该出现“cccaaa”和“scn-aaa”这两个词。
我试过grep -w
但没有运气
$ grep -w "aaa" Log.txt
aaa xxx zzz
scn-aaa
$ grep -w "\<aaa\>" Log.txt
aaa xxx zzz
scn-aaa
我也试过-Fx
但没有帮助。
请告诉我如何使用grep
命令实现此目的。
注意:每行可能有多个不固定的列。
答案 0 :(得分:3)
grep -w
计算&#39; - &#39;作为开始一个单词边界,这就是它捕捉scn-aaa的原因。简而言之,你想做什么-w做什么,但对有效单词字符的构成有不同的定义。
对于grep,单词字符为[_[:alnum:]]
,即任何字母或数字或下划线字符。所以我们可以通过以下方式滚动我们自己的grep -w匹配:
grep -E '(^|[^[:alnum:]_-])aaa($|[^[:alnum:]_-])'
也就是说,在字符串的开头或结尾之前和之后匹配aaa,或者匹配非字字符,我们在其中计算&#39; - &#39;也是一个单词角色。
答案 1 :(得分:1)
也可以使用awk
awk -F"[^[:alnum:]_-]" '{f=0;for (i=1;i<=NF;i++) if ($i=="aaa") f=1}f' file
aaa xxx zzz
cccaaa yy aaa
这里我们设置的字段分隔符不是任何字母,数字,也不是_
和-
然后逐个测试每个字段。如果找到一个匹配,请打印该行。
出于某种原因,即使我们设置了正确的分隔符,awk
中的单词边界也会失败,所以不要使用它:
awk -F"[^[:alnum:]_-]" '/\<aaa\>/' file
aaa xxx zzz
cccaaa yy aaa
scn-aaa
答案 2 :(得分:1)
我使用了很多建议,但最适合我的是以下命令:
grep -E '(^|\s)'<PATTERN>'($|\s)' <FILENAME>
以下是一个例子:
$ cat Log.txt
aaa xxx zzz
bbb xxx aa
cccaaa yy aa
scn-aaa
$ i=aaa
$ grep -E '(^|\s)'${i}'($|\s)' Log.txt
aaa xxx zzz
感谢大家的建议: - )
答案 3 :(得分:0)
您可以尝试:
grep -P '(?<!\w-)(aaa)(?![\w-])'
匹配aaa
未跟随或先于a-zA-Z0-9
或-
之一的?<!
。
aaa
是一个负面的背后隐藏 - 确保\w-
之前的?!
{<1}}
aaa
是一个负面的预测 - 确保\w-
未遵循 bye {{1}}