用于查看文件内部的管道 grep

用于查看文件内部的管道 grep

(从ask-ubuntu自行迁移,因为它与linux相关,而不是ubuntu,而且我的操作系统不是ubuntu)

我正在尝试制作一个如下所示的 grep:

grep -r 2019 | grep -riv FAILED | grep -rl DSL

我想获取其中-l包含的文件的文件名 ( ) ,而不是 ( ) 包含AND 包含.2019-vFAILEDDSL

这里只执行最后一个grep。我知道这是因为-r,所以每个 grep 都会对所有文件进行 grep,而不是之前的结果。但我不知道如何让它在没有-r.

也许还有另一种方法可以在 grep 上使用多个模式,但对于“正”和“负”匹配,我没有找到任何内容。

答案1

grep管道中的最后一个将从前一个读取grep(如果它没有使用该-r选项,请参阅稍后),因此它不知道从什么文件数据来自,这又意味着它无法报告文件的路径名。

相反,请考虑find像这样使用:

find . -type f \
    -exec grep -q 2019 {} \; \
    -exec grep -q DSL {} \; \
    ! -exec grep -qi FAILED {} \; \
    -print

这将从当前目录和任何子目录中获取每个常规文件(递归地)并测试它是否包含字符串2019, DSL, 和FAILED(不区分大小写)。它将打印包含前两个字符串但不包含第三个字符串的文件的路径名。

如果文件不包含2019则不进行另外两个测试,如果不包含DSL则不进行最后一个测试,依此类推。

请注意,grep -v -qi FAILED我没有使用 的否定grep -qi FAILED作为第三个测试。我对文件是否包含不包含的行不感兴趣FAILED,我感兴趣的是文件是否包含包含 FAILED,在这种情况下我想跳过这个文件。

有关的:


你的管道问题,

grep -r 2019 | grep -riv FAILED | grep -rl DSL

是最后一个grep将递归地查找当前目录及以下目录中的所有文件,并将忽略管道前一阶段的输入。两个初始grep调用可能会产生一些数据,但它们无法通过管道转发这些数据,并且最终会在最后一个调用grep完成时被杀死。

另外,正如我上面已经指出的,中间grep不会找到不包含 的文件FAILED,它会找到包含除FAILED。顺便说一句,它会忽略前面的输入grep

答案2

与 GNU grep-r已经是 GNU 扩展)和 GNUxargs或兼容:

grep -rlZ 2019 . |
  xargs -r0 grep -LiZ FAILED |
  xargs -r0 grep -l DSL

您需要xargs能够传递文件列表输出由一grep作为论点到下一个grep。并且-Z该文件列表以 NUL 分隔。要报告不包含 FAILED 的文件列表,它-L(也是 GNU 扩展),而不是-vl报告包含至少一行不匹配的文件。

这应该将调用次数限制grep在最低限度,并且对于大量文件,可以同时利用最多三个处理器。

相关内容