使用grep或其他命令返回多行模式的行号

Alp*_*ric 3 linux awk grep sed less-unix

我正在使用该less命令浏览一个非常大的文本日志文件(15 GB),并尝试搜索多行模式,但是经过一些调查,该less命令只能搜索单行模式。

有没有一种方法可以使用grep或其他命令来返回多行模式的数字行?

日志的格式是这样的,经过数十万次迭代:

Packet A
op_3b       : 001
ctrl_2b     : 01
ini_count   : 5

Packet F
op_3b       : 101
ctrl_2b     : 00
ini_count   : 4

Packet X
op_3b       : 010
ctrl_2b     : 11
ini_count   : 98

Packet CA
op_3b       : 100
ctrl_2b     : 01
ini_count   : 5

Packet LP
op_3b       : 001
ctrl_2b     : 00
ini_count   : 0

Packet ZZ
op_3b       : 111
ctrl_2b     : 01
ini_count   : 545

Packet QEA
op_3b       : 111
ctrl_2b     : 11
ini_count   : 0
Run Code Online (Sandbox Code Playgroud)

而我想要得到的是拥有grep或其他命令来返回出现这三行模式时的行号开头:

op_3b       : 001
ctrl_2b     : 00
ini_count   : 0
Run Code Online (Sandbox Code Playgroud)

Joh*_*024 5

假设该模式在文件中pattern如下所示:

$ cat pattern
op_3b       : 001
ctrl_2b     : 00
ini_count   : 0
Run Code Online (Sandbox Code Playgroud)

然后,尝试:

$ awk '$0 ~ pat' RS=  pat="$(cat pattern)" logfile
Packet LP
op_3b       : 001
ctrl_2b     : 00
ini_count   : 0
Run Code Online (Sandbox Code Playgroud)

怎么运行的

  • RS=

    这会将“记录分隔符” RS设置为空字符串。这告诉awk使用空行作为记录分隔符。

  • pat="$(cat pattern)"

    这告诉awk创建一个pat包含文件内容的awk变量pattern

    如果您的shell是bash,则此命令的形式会稍微更有效pat="$(<pattern)"。(除非确定您的外壳是bash,否则不要使用它。)

  • $0 ~ pat

    这告诉awk打印与模式匹配的任何记录。

    $0是当前记录的内容。 ~告诉awk在中的文本$0和中的正则表达式之间进行匹配pat

    (如果中的内容pattern具有任何正则表达式活动字符,我们将需要对其进行转义。您当前的示例中没有任何正则表达式,因此这不是问题。)

另类风格

有些人喜欢使用不同的样式来定义awk变量:

$ awk -v RS=  -v pat="$(cat pattern)" '$0 ~ pat' logfile
Packet LP
op_3b       : 001
ctrl_2b     : 00
ini_count   : 0
Run Code Online (Sandbox Code Playgroud)

这是一样的。

显示行号

$ awk -F'\n' '$0 ~ pat{print "Line Number="n+1; print "Packet" $0} {n=n+NF-1}' RS='Packet'  pat="$(cat pattern)" logfile
Line Number=20
Packet LP
op_3b       : 001
ctrl_2b     : 00
ini_count   : 0
Run Code Online (Sandbox Code Playgroud)