Kra*_*out 3 grep sed find awk pattern-matching
我需要找到.php不.pl包含一个字符串(例如aaa)但包含另一个字符串(例如bbb)的文件。
我目前正在使用这个命令:
find /path/ \( -iname '*.php*' -or -name '*.pl*' \) -exec sh -c 'grep -l -v "aaa" {} | grep -l "bbb" {}' \; > resulttofile
Run Code Online (Sandbox Code Playgroud)
大约有 50 万个文件需要搜索,所以我想知道,
awkorsed代替grep- 或者可能只是一种组合grep而不是两种。该系统是 Debian GNU/Linux。
您的命令\xe2\x80\x99t 无法正常工作:第一个命令grep将列出包含不匹配行的任何文件"aaa",第二个命令grep将忽略第一个\xe2\x80\x99s 输出,因为它\xe2\x80\x99s 给出了自己的输出文件来处理 \xe2\x80\x94 这样你\xe2\x80\x99就会得到一个匹配的文件列表"bbb",无论它们"aaa"是否包含。您\xe2\x80\x99d 需要要求grep仅列出一个文件,如果它不\xe2\x80\x99t 包含任何匹配的行"aaa"(grep -L),并使用xargs处理结果文件列表并仅将其提供给第二个文件grep(或使第二个grep以第一个的结果为条件)。
最重要的是,只有当find列出 don\xe2\x80\x99t 的文件名对 shell \xe2\x80\x94 造成问题时,它才会起作用,特别是,包括{}直接在给出的命令中sh -c意味着文件名可以结束up 被解释为 shell 命令(有关详细信息,请参阅是否可以安全地使用 `find -exec sh -c`? )。
假设您\xe2\x80\x99 使用 GNU ,以下内容将需要更少的grep调用并且更安全grep:
find /path/ \\( -iname \'*.php*\' -o -name \'*.pl*\' \\) -exec grep -LZ aaa {} + |\n xargs -r0 grep -l bbb\nRun Code Online (Sandbox Code Playgroud)\n该运算符是.\xc2\xa0\n的-orGNU 扩展,用于实现可移植性。find-o
未经测试,但这应该做我认为你想要的,使用 GNU awk fornextfile和ENDFILE
find /path/ \\( -iname \'*.php*\' -or -name \'*.pl*\' \\) -exec awk \'\n /aaa/{a=1} /bbb/{b=1} a&&b{nextfile} ENDFILE{if (b && !a) print FILENAME; a=b=0}\n\' {} + > resulttofile\nRun Code Online (Sandbox Code Playgroud)\n上面一次只对多个文件调用 awk 一次,因此应该是高效的。
\n上面是如何通常匹配文件中的多个模式,然后在完全读取文件后评估匹配组合的结果,但正如@G-Man 在评论中提到的“恢复 Monica”,您可以做到这一点在这种特定情况下,通过在匹配时停止读取当前文件来提高效率,因为成功标准是不存在:aaaaaa
/aaa/{a=1;\xe2\x80\xafnextfile} /bbb/{b=1} ENDFILE{if\xe2\x80\xaf(b\xe2\x80\xaf&&\xe2\x80\xaf!a) print\xe2\x80\xafFILENAME; a=b=0}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
658 次 |
| 最近记录: |