我正在使用grep -w -f
从与模式匹配的文件中提取行。但是,如果输入模式文件中的模式与模式不完全匹配,则它似乎屏蔽了稍后在输入模式文件中出现的完整匹配。我还缺少另一个grep
选项吗?例如:
$ head list
tt140
tt1351
tt1354
tt998
tt1122
$ head match1
tt135
tt1122
tt1351
$ grep -w -f match1 list
tt1122
tt135
中的第一个模式match1
似乎会干扰后来的tt1351
。如果删除第一行,则会报告tt1351
匹配。
$ head match2
tt1122
tt1351
$ grep -w -f match2 list
tt1351
tt1122
这是预期的行为吗?是否有另一种选择传递给grep
以避免这种情况?
答案 0 :(得分:3)
事实上,正如@japyal所述, BSD 版本grep
中似乎存在错误(这也会影响OSX)。
解决方法强>:
grep -f <(sed 's/.*/\\<&\\>/' match1) list
这会动态地将match1
中的字符串包含在显式字边界正则表达式断言中,就像match1
被定义为:
\<tt135\>
\<tt1122\>
\<tt1351\>
净效果与指定-w
的效果相同。
答案 1 :(得分:0)
如果你不能按照mklement0的建议修改match1,你可以使用shell cmds创建-w -f功能来构造一个等效的grep cmd:
> egrep `cat match1 | xargs -d '\n' | sed 's/^/(\\</; s/$/\\>)/; s/ /\\>|\\</g;'` list
tt1351
tt1122
我没有Mac或BSD来验证,但这适用于我。
说明:反引号中的部分正在构造所需的正则表达式,然后在香草egrep cmd中使用。
> cat match1 | xargs -d '\n' | sed 's/^/(\\</; s/$/\\>)/; s/ /\\>|\\</g;'
(\<tt135\>|\<tt1122\>|\<tt1351\>)