使用sed或awk按照匹配模式打印一行

use*_*723 55 awk sed

我想直接在包含匹配模式的行之后打印一行.我的版本sed不会采用以下语法(它炸弹了+1p.)这看起来像一个简单的解决方案:

sed -n '/ABC/,+1p' infile
Run Code Online (Sandbox Code Playgroud)

我认为awk做多线处理会更好,但我不知道该怎么做.

Ed *_*ton 125

永远不要使用"模式"这个词,因为它非常含糊不清.始终使用"string"或"regexp"(或在shell中使用"globbing pattern"),无论你的意思是什么.

你想要的具体答案是:

awk 'f{print;f=0} /regexp/{f=1}' file
Run Code Online (Sandbox Code Playgroud)

或者在正则表达式之后专门化第N个记录的更一般的解决方案(下面的成语"c"):

awk 'c&&!--c; /regexp/{c=1}' file
Run Code Online (Sandbox Code Playgroud)

以下习语描述了如何在给定特定正则表达式匹配的情况下选择一系列记录:

a)打印来自某些正则表达式的所有记录:

awk '/regexp/{f=1}f' file
Run Code Online (Sandbox Code Playgroud)

b)在一些正则表达式后打印所有记录:

awk 'f;/regexp/{f=1}' file
Run Code Online (Sandbox Code Playgroud)

c)在一些正则表达式后打印第N条记录:

awk 'c&&!--c;/regexp/{c=N}' file
Run Code Online (Sandbox Code Playgroud)

d)在一些正则表达式之后打印除第N个记录之外的每个记录:

awk 'c&&!--c{next}/regexp/{c=N}1' file
Run Code Online (Sandbox Code Playgroud)

e)在一些正则表达式后打印N条记录:

awk 'c&&c--;/regexp/{c=N}' file
Run Code Online (Sandbox Code Playgroud)

f)在一些regexp之后打印除N条记录之外的每条记录:

awk 'c&&c--{next}/regexp/{c=N}1' file
Run Code Online (Sandbox Code Playgroud)

g)从一些正则表达式打印N条记录:

awk '/regexp/{c=N}c&&c--' file
Run Code Online (Sandbox Code Playgroud)

我从"F"改为变量名的"发现",以"C"为"计数"在适当情况下为这更多表现的是什么变量实际上是.

  • @Josh `f` 是 `found` 的缩写。当我在输入中找到与正则表达式“regexp”匹配的字符串(“/regexp/{f=1}”)时,我将其设置为“1”(true)的布尔标志。您在每个脚本中单独看到“f”的另一个地方,它作为一个条件进行测试,当 true 时,会导致 awk 执行打印当前记录的默认操作。因此,只有在我们看到“regexp”并将 f 设置为 1/true 后,输入记录才会获得输出。 (5认同)
  • 你能解释一下``c &&! - c``的作用吗?谢谢! (4认同)
  • 如果c非零,则递减它并测试它是否为零.因此,如果c以某个正数开始,则在从该数字向下计数到零之后将执行相关的操作."如果c非零"部分是一个保护,以确保c不会继续进入负数,并且如果输入文件很大,可能会再次回到正数. (3认同)
  • @EdMorton,你介意解释一下(a)和(b)中的“f”在做什么吗?谢谢。 (2认同)

cho*_*ban 37

这是行那场比赛,你在有趣,对吧?在sed中,可以像这样完成:

sed -n '/ABC/{n;p}' infile
Run Code Online (Sandbox Code Playgroud)

或者,grep的A选项可能是您正在寻找的选项.

-A NUM, Print NUM lines of trailing context after matching lines.
Run Code Online (Sandbox Code Playgroud)

例如,给定以下输入文件:

foo
bar
baz
bash
bongo
Run Code Online (Sandbox Code Playgroud)

您可以使用以下内容:

$ grep -A 1 "bar" file
bar
baz
$ sed -n '/bar/{n;p}' file
baz
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • 更正:我通过添加`;`:`sed -n/bar/{n; p;}`在BSD sed上取得了成功.也适用于GNU sed. (5认同)

Mar*_*ark 5

我需要在模式之后打印所有行(好的Ed,REGEX),所以我选择了这一行:

sed -n '/pattern/,$p' # prints all lines after ( and including ) the pattern
Run Code Online (Sandbox Code Playgroud)

但是由于我想在之后打印所有行(并排除模式)

sed -n '/pattern/,$p' | tail -n+2  # all lines after first occurrence of pattern
Run Code Online (Sandbox Code Playgroud)

我想在您的情况下,您可以head -1在末尾添加一个

sed -n '/pattern/,$p' | tail -n+2 | head -1 # prints line after pattern
Run Code Online (Sandbox Code Playgroud)

  • 您的第二种情况有一种严格的 sed 方法:`sed '0,/regex/d'` (2认同)