我正在尝试构建一个 grep 搜索,用于搜索一个术语,但排除包含第二个术语的行。我想使用多个-e "pattern"
选项,但没有奏效。
这是我尝试过的命令及其生成的错误消息的示例。
grep -i -E "search term" -ev "exclude term"
grep: exclude term: No such file or directory
我觉得这适用于所有搜索词/模式。虽然这可以运行,但结果中-v
不包括。search term
grep -i -E "search term" -ve "exclude term"
答案1
到和使用 grep 表达式需要两次调用:
grep -Ei "search term" | grep -Eiv "exclude term"
如果搜索的术语不是正则表达式,请使用-F
速度更快的固定字符串匹配():
grep -F "search term" | grep -Fv "exclude term"
答案2
除了调用 grep 两次之外,我能想到的唯一方法就是完成此操作。它涉及Perl 兼容正则表达式(PCRE)和一些相当 hacked环视断言。
搜索富排除包含以下内容的匹配项酒吧, 您可以使用:
grep -P '(?=^((?!bar).)*$)foo'
工作原理如下:
(?!bar)
匹配任何不酒吧不消耗字符串中的字符。然后.
消耗单个字符。^((?!bar).)*
从字符串的开头 (^
) 到结尾 ( ) 重复上述操作。如果在任何给定点遇到 ,$
它将失败,因为将不匹配。bar
(?!bar)
(?=^((?!bar).)*$)
确保字符串与前一个模式匹配,但不消耗字符串中的字符。foo
搜索富照常。
我发现这个 hack正则表达式匹配不包含单词的字符串?。 在Bart Kiers 的回答,你可以找到关于负向前瞻如何运作的更详细解释。
答案3
如果您想一次性完成此操作,可以使用 awk 而不是 grep。
格式:
echo "some text" | awk '/pattern to match/ && !/pattern to exclude/'
例子:
echo "hello there" | awk '/hello/ && !/there/'
不返回任何内容。
echo "hello thre" | awk '/hello/ && !/there/'
返回:你好
echo "hllo there" | awk '/hello/ && !/there/'
不返回任何内容。
对于多个模式,可以使用括号对它们进行分组。
例子:
echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'
返回:你好
echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'
返回:嗨
echo "hello there" | awk '(/hello/ || /hi/) && !/there/'
不返回任何内容。
echo "hi there" | awk '(/hello/ || /hi/) && !/there/'
不返回任何内容。
答案4
grep
从我的实验来看,如果你通过或 来管道化排除项,似乎不会产生太大影响sed
。Sed 还有一些其他有用的文本替换功能,我经常使用这些功能来更好地过滤日志文件的输出。因此,我将使用 sed,因为我在 sed 上组合了相当多的过滤器。
wc /var/log/tomcat/tomcat.2013-01-14.log.1 1851725 /usr/bin/time grep -i -E“(loginmanager)”/var/log/tomcat/tomcat.2013-01-14.log.1 | sed -e“/login OK/d”-e“/Login expired/d”| wc 24.05用户 0.15系统 0:25.27已用 95%CPU (0avgtext+0avgdata 3504maxresident)k 0 输入 + 0 输出 (0 主 + 246 次要) 页面错误 0 交换 5614 91168 1186298 /usr/bin/time grep -i -E“(loginmanager)”/var/log/tomcat/tomcat.2013-01-14.log.1 | sed -e“/login OK/d”-e“/Login expired/d”| wc 23.50用户 0.16系统 0:24.48已用 96%CPU (0avgtext+0avgdata 3504maxresident)k 0 输入 + 0 输出 (0 主 + 246 次要) 页面错误 0 交换 5614 91168 1186298 /usr/bin/time grep -i -E “(loginmanager)” /var/log/tomcat/tomcat.2013-01-14.log.1 | grep -v -e “login OK” -e “登录已过期” | wc 23.08用户 0.14系统 0:23.55已用 98%CPU (0avgtext+0avgdata 3504maxresident)k 0 输入 + 0 输出 (0 主 + 246 次要) 页面错误 0 交换 5614 91168 1186298 /usr/bin/time grep -i -E “(loginmanager)” /var/log/tomcat/tomcat.2013-01-14.log.1 | grep -v -e “login OK” -e “登录已过期” | wc 23.50用户 0.15系统 0:25.27已用 93%CPU (0avgtext+0avgdata 3488maxresident)k 0 输入 + 0 输出 (0 主 + 245 次要) 页面错误 0 交换 5614 91168 1186298