Negative matching using grep (match lines that do not contain foo)
我一直在尝试为这个命令制定语法:
1
| grep ! error_log | find /home/foo/public_html/ -mmin -60 |
或
1
| grep '[^error_log]' | find /home/baumerf/public_html/ -mmin -60 |
我需要查看除了那些名为error_log的文件之外所有已修改的文件。
我在这里读过,但只找到一个notregex模式。
- [^error_log]无论如何都不会工作,[]是char类,regexp通常不擅长负模式(除非引擎实现负lookaheads)。
grep -v是你的朋友:
1
| grep --help | grep invert |
-v, --invert-match select non-matching lines
还可以查看相关的-L(-L的补充)。
-L, --files-without-match only print FILE names containing no match
- 值得一提的是,对于多个(负)匹配的-e选项可以使用:grep -v -e 'negphrase1' -e 'negphrase2'。
- 类似于@babken vardanyan的评论-也可以使用管道连接多个匹配项,例如grep -v 'negphrase1|negphrase2|negphrase3'。
- 最后一条评论与它将搜索不匹配的内容不同,而不是两者都匹配。如果它与一个匹配,但另一个不匹配,它仍然是印刷的。用不相似的字符串尝试两种方法
- 如果我们有grep1 | grep2 -v,那么-v效应也会发生在grep1上,所以首先是grep not expected,然后是grep expected。
- @Evanlanglois-迫使grep使用-e工程将模式解释为扩展正则表达式,即grep -vE 'negphrase1|negphrase2|negphrase3'。
- @兹勒米尼-是的,那行得通,但尼古拉斯·亚当斯的台词不行。
- 这个解决方案不适用于一个用例:如果我想要包含foo但不包含bar的行的文件名。
- @奥利&228;rstedt,我想我在我之前的评论中误解了你的想法,下面可能是你在找的grep"" /dev/null * | grep foo | grep -v bar | cut -d: -f1 | sort -u(为什么是第一个grep?,总有办法:)
您也可以使用awk来实现这些目的,因为它允许您以更清晰的方式执行更复杂的检查:
不包含foo的行:
既不包含foo也不包含bar的行:
既不包含foo也不包含bar的行,其中包含foo2或bar2:
1
| awk '!/foo/ && !/bar/ && (/foo2/ || /bar2/)' |
等等。
- 这真的很酷。为了用逻辑运算符对regexp进行分组,甚至不需要学习完整的awk语言。谢谢你的回答!
在您的例子中,您可能不想使用grep,而是在find命令中添加一个否定子句,例如。
1
| find /home/baumerf/public_html/ -mmin -60 -not -name error_log |
如果要在名称中包含通配符,则必须对其进行转义,例如排除后缀为.log的文件:
1
| find /home/baumerf/public_html/ -mmin -60 -not -name \*.log |