我正在使用 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 6
word3
cat … | awk …
您可以轻松添加更多具有自己的值的正则表达式
n
,例如。请注意,您将使用的/word4/ && n<3 { n=3 }
值(此处)出现在两个地方;我选择了grep
-A
3
吻超过干燥。如果一行匹配多个模式,则匹配最大的模式
n
将获胜。所谓“尾随上下文”中的匹配行
man grep
只能使上下文变长,而不能使上下文变短。换句话说,如果您将文件想象为有序的行集,那么从我们的代码中您将获得所有匹配行和尾随上下文的并集。grep -A
可能会打印组分隔符。您的示例不包含任何分隔符,因此我们的awk
代码不会受到影响。我们代码中的模式匹配区分大小写。我注意到你使用了
grep -i
。请参阅这个答案并根据需要调整代码(替换/word1|word2/
为tolower($0) ~ /word1|word2/
等)。请注意,您可以单独调整或不调整每个模式。