grep 跳过 n 行文件,只搜索

kol*_*nep 9 grep

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

例如:

123
XXY
214
ABC
182
558
ABC
856
ABC
Run Code Online (Sandbox Code Playgroud)

在我的例子中,我想找到182然后找到下一次出现ABC

第一次出现很简单:

grep -n -m1 "182" /var/log/file
Run Code Online (Sandbox Code Playgroud)

这输出:

5:182
Run Code Online (Sandbox Code Playgroud)

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

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

mik*_*erv 11

有了sed您可以使用范围,并q在一个单一的完成UIT输入:

sed '/^182$/p;//,/^ABC$/!d;/^ABC$/!d;q'
Run Code Online (Sandbox Code Playgroud)

与 GNU 类似,grep您可以在两个greps之间拆分输入:

{ grep -nxF -m1 182; grep -nxF -m1 ABC; } <<\IN
123
XXY
214
ABC
182
558
ABC
856
ABC
IN
Run Code Online (Sandbox Code Playgroud)

...打印...

5:182
2:ABC
Run Code Online (Sandbox Code Playgroud)

...表示第一个grep找到-F固定字符串文字,-x整行182匹配从其读取开始的 5 行,第二个发现类似类型的ABC匹配从其读取开始的 2 行 - 或 2 行第5 行第一次grep 退出阅读之后

来自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. 
Run Code Online (Sandbox Code Playgroud)

为了可重复的演示,我使用了一个 here-document,但你可能应该这样做:

{ grep ...; grep ...; } </path/to/log.file
Run Code Online (Sandbox Code Playgroud)

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

for p in 182 ABC; do grep -nxFm1 "$p"; done </path/to/log.file
Run Code Online (Sandbox Code Playgroud)