从shell获得两行

Adr*_*anL 1 bash awk grep sed

我用

cmd | egrep 'ID|Value'
Run Code Online (Sandbox Code Playgroud)

在我的命令行上输出以下输出:

    ID: 2
Value: 21
    ID: 1
Value: 25
    ID: 1
Value: 22
    ID: 3
Value: 56
    ID: 1
Value: 23
    ID: 2
Value: 50
    ID: 2
Value: 56
    ID: 3
Value: 11
    ID: 3
Value: 26
Run Code Online (Sandbox Code Playgroud)

我想用一个特殊ID过滤它.但是当我使用时:

egrep 'ID: 1|Value'
Run Code Online (Sandbox Code Playgroud)

它将仅使用ID 1显示相同的输出,但显示所有ID的值.

我已经读过关于awk,sed和regex的内容了,但我找不到任何可以帮助我的东西,但我也没那么深入.

有人可以提出一个想法,或者告诉我这是一个错误的方法,我应该采取不同的方式,如何做?

按需输出:

    ID: 1
Value: 25
    ID: 1
Value: 22
    ID: 1
Value: 23
Run Code Online (Sandbox Code Playgroud)

fed*_*qui 8

告诉grep我们将匹配的行与下一行一起打印出来:

$ grep -A1 'ID: 1$' file
    ID: 1
Value: 25
    ID: 1
Value: 22
--
    ID: 1
Value: 23
Run Code Online (Sandbox Code Playgroud)

来自man grep:

-A NUM, - after-context = NUM

匹配行后打印NUM行尾随上下文.在连续的匹配组之间放置一个包含组分隔符( - )的行.使用-o或--only-matching选项,这不起作用,并给出警告.

注意$用于标记行尾的用法.否则,这将匹配线条线ID: 1323423423.

如果你不喜欢--在比赛之间出现,可以用以下方法摆脱它:

grep -A1 --no-group-separator 'ID: 1$' file
#        ^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

  • 请注意,-A1表示"之后",如果您想要该行之前可以使用-B1("之前") (2认同)
  • @Alan完全正确.如果您的"之后"和"之前"匹配,您可以使用`-C`加入它们. (2认同)

gle*_*man 6

对于其他标签:

AWK

awk '/ID: 1$/ {print; getline; print}'
Run Code Online (Sandbox Code Playgroud)

sed,非常相似

sed -n '/ID: 1$/ {p;n;p}'
Run Code Online (Sandbox Code Playgroud)

和bash

while read line; do if [[ $line == *"ID: 1" ]]; then echo "$line"; read line; echo "$line"; fi; done
Run Code Online (Sandbox Code Playgroud)

  • 这就是没有剪切和粘贴的问题. (2认同)

Ini*_*ian 5

另一个简单的脚本使用 awk

awk '/ID: 1/{line[NR]; line[NR+1]}; NR in line' file
Run Code Online (Sandbox Code Playgroud)

将输出作为: -

    ID: 1
Value: 25
    ID: 1
Value: 22
    ID: 1
Value: 23
Run Code Online (Sandbox Code Playgroud)

NR是一个awk存储记录号的特殊变量.我们所要做的是匹配的模式,并获得NthN+1th记录在该行的文件打印,并确保要打印的记录是很好的最大范围内,在该行(NR in line).