过滤与Grep完全匹配

时间:2015-03-05 08:14:00

标签: regex bash unix grep

我一直在广泛使用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命令实现此目的。

注意:每行可能有多个不固定的列。

4 个答案:

答案 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}}