grep 跳过 n 行文件并仅搜索之后的内容

grep 跳过 n 行文件并仅搜索之后的内容

我有一个巨大的日志文件,想要 grep 第一次出现的模式,然后找到另一个模式就在之后这种情况的发生。

例如:

123
XXY
214
ABC
182
558
ABC
856
ABC

在我的例子中,我想找到182然后找到下一个的发生ABC

第一次出现很简单:

grep -n -m1 "182" /var/log/file

这输出:

5:182

如何找到下一个出现的 ABC?

我的想法是根据行号 182告诉grep跳过第一n行(在上面的示例中)。但是我该怎么做呢?n=5

答案1

您可以在一次完成中sed使用范围和uit 输入:q

sed '/^182$/p;//,/^ABC$/!d;/^ABC$/!d;q'

类似地,在 GNU 中,grep您可以将输入拆分为两个grep

{ grep -nxF -m1 182; grep -nxF -m1 ABC; } <<\IN
123
XXY
214
ABC
182
558
ABC
856
ABC
IN

...打印...

5:182
2:ABC

...表示第一个grep找到了-F固定字符串文字,-x整行182从读取开始匹配 5 行,第二个找到类似类型的ABC从读取的开头匹配 2 行 - 或 2 行首先grep 辞职阅读第 5 行。

man grep

-m NUM, --max-count=NUM
          Stop  reading  a  file  after  NUM  matching
          lines.   If the input is standard input from
          a regular file, and NUM matching  lines  are
          output, grep ensures that the standard input
          is  positioned  to  just  after   the   last
          matching  line before exiting, regardless of
          the  presence  of  trailing  context  lines.
          This  enables  a calling process to resume a
          search. 

为了可重现的演示,我使用了此处文档,但您可能应该这样做:

{ grep ...; grep ...; } </path/to/log.file

它还可以与其他 shell 复合命令结构一起使用,例如:

for p in 182 ABC; do grep -nxFm1 "$p"; done </path/to/log.file

答案2

grep与 Perl 兼容的正则表达式 ( ) 一起使用pcregrep

pcregrep -Mo '182(.|\n)*?\KABC'

选项-M允许模式匹配多行,并且\K不将匹配的模式(到目前为止)包含到输出中。\K如果您想获得整个区域,则可以将其删除。

答案3

> awk '/^182$/ { startline=1; }; startline == 0 { next; }; /^ABC$/ { print "line " NR ": " $0; exit; }' file
line 7: ABC

答案4

另一种变体是这样的:

grep -n -A99999 "182" /var/log/file|grep -n -m1 "ABC"

标志 -An 在比赛后 grep n 行和 99999 只是为了确保我们不会错过任何东西。较大的文件应该有更多的行(使用“wc -l”检查)。

相关内容