如何在字符串/搜索中将“搜索多个字符串(模式)”与“命中后打印行”结合起来并输出一个公共文件?

如何在字符串/搜索中将“搜索多个字符串(模式)”与“命中后打印行”结合起来并输出一个公共文件?

我正在使用 Windows 版本的 grep“GNU Grep”。

syntax: grep [OPTIONS] PATTERN [FILE...]

我如何将不同的选项与不同的模式相结合?

这里列出的两条线路都可以单独使用。但我还没有成功地将它们结合起来。

grep -i -a -h -E "word1|word2" INfilename.log* > "OUTfilename.txt"
grep -i -a -h -A 6 "word3" INfilename.log* > "OUTfilename.txt"

输入示例:

2023-07-29 11:31:01 bla something bla
2023-07-29 11:31:02 bla word1 bla
2023-07-29 11:31:03 bla something bla
2023-07-29 11:31:04 bla word2 bla
2023-07-29 11:31:05 bla something bla
2023-07-29 11:31:06 bla word3 bla
2023-07-29 11:31:07 bla something bla
2023-07-29 11:31:08 bla something bla
2023-07-29 11:31:09 bla something bla
2023-07-29 11:31:10 bla something bla
2023-07-29 11:31:11 bla something bla
2023-07-29 11:31:12 bla something bla
2023-07-29 11:31:13 bla something bla

结果应如下所示:

2023-07-29 11:31:02 bla word1 bla
2023-07-29 11:31:04 bla word2 bla
2023-07-29 11:31:06 bla word3 bla
2023-07-29 11:31:07 bla something bla
2023-07-29 11:31:08 bla something bla
2023-07-29 11:31:09 bla something bla
2023-07-29 11:31:10 bla something bla
2023-07-29 11:31:11 bla something bla
2023-07-29 11:31:12 bla something bla

答案1

我认为您无法使用 来做到这一点grep-A这是一个全局选项,无法将其应用于模式子集。您需要一个更通用的工具来编写所需的逻辑。

以下awk代码与您的示例配合良好:

#!/bin/awk -f
FNR==1 { n=-1 }
/word1|word2/ && n<0 { n=0 }
/word3/       && n<6 { n=6 }
n>=0 { n--; print }

笔记:

  • 我是一名 Linux 用户,不使用 Windows。该代码是 Linux 的脚本。如果您可以awk在 Windows 中运行,您至少应该能够通过将代码保存在文件中并调用来运行该代码awk -f path_to_the_file。我猜测此命令也有效:

    awk "FNR==1 { n=-1 } /word1|word2/ && n<0 { n=0 } /word3/ && n<6 { n=6 } n>=0 { n--; print }"
    
  • 可以使用一个或多个路径名作为附加参数来调用脚本(或命令),以指定从中读取输入的文件;所以这应该是可能的:

    awk … INfilename.log*
    

    (至少在 Linux 中可以工作)。请注意,当我们的代码继续处理下一个文件时,会故意重置,因此在接近一个文件末尾时触发的模仿n的行为不会延伸到下一个文件。如果要将多个文件的内容视为一个流,请先连接这些文件(在 Linux 中:)。grep-A 6word3cat … | awk …

  • 您可以轻松添加更多具有自己的值的正则表达式n,例如。请注意,您将使用的/word4/ && n<3 { n=3 }值(此处)出现在两个地方;我选择了grep-A3超过干燥

  • 如果一行匹配多个模式,则匹配最大的模式n将获胜。

  • 所谓“尾随上下文”中的匹配行man grep只能使上下文变长,而不能使上下文变短。换句话说,如果您将文件想象为有序的行集,那么从我们的代码中您将获得所有匹配行和尾随上下文的并集。

  • grep -A可能会打印组分隔符。您的示例不包含任何分隔符,因此我们的awk代码不会受到影响。

  • 我们代码中的模式匹配区分大小写。我注意到你使用了grep -i。请参阅这个答案并根据需要调整代码(替换/word1|word2/tolower($0) ~ /word1|word2/等)。请注意,您可以单独调整或不调整每个模式。

相关内容