使用sed或awk打印符合匹配图案的线条

使用sed或awk打印符合匹配图案的线条,awk,sed,Awk,Sed,问题:我想在包含匹配图案的行后面直接打印一行 我的sed版本不会采用以下语法(它在+1p上爆炸),这似乎是一个简单的解决方案: sed -n '/ABC/,+1p' infile 我认为多行处理比awk更好,但我不知道怎么做。这是你感兴趣的匹配后的行,对吗?在sed中,可以这样完成: sed -n '/ABC/{n;p}' infile 或者,grep的选项可能就是您想要的 -A NUM, Print NUM lines of trailing context after matching

问题:我想在包含匹配图案的行后面直接打印一行

我的
sed
版本不会采用以下语法(它在
+1p
上爆炸),这似乎是一个简单的解决方案:

sed -n '/ABC/,+1p' infile
我认为多行处理比awk更好,但我不知道怎么做。

这是你感兴趣的匹配后的行,对吗?在sed中,可以这样完成:

sed -n '/ABC/{n;p}' infile
或者,grep的选项可能就是您想要的

-A NUM, Print NUM lines of trailing context after matching lines.
例如,给定以下输入文件:

foo
bar
baz
bash
bongo
您可以使用以下选项:

$ grep -A 1 "bar" file
bar
baz
$ sed -n '/bar/{n;p}' file
baz
希望这会有帮助。

你对那场比赛后的台词感兴趣,对吗?在sed中,可以这样完成:

sed -n '/ABC/{n;p}' infile
或者,grep的选项可能就是您想要的

-A NUM, Print NUM lines of trailing context after matching lines.
例如,给定以下输入文件:

foo
bar
baz
bash
bongo
您可以使用以下选项:

$ grep -A 1 "bar" file
bar
baz
$ sed -n '/bar/{n;p}' file
baz
希望对您有所帮助。

awk版本:

awk '/regexp/ { getline; print $0; }' filetosearch
awk版本:

awk '/regexp/ { getline; print $0; }' filetosearch
永远不要使用“模式”这个词,因为它是高度模糊的。始终使用“string”或“regexp”(或shell中的“globbing模式”),无论您真正的意思是什么

您想要的具体答案是:

awk 'f{print;f=0} /regexp/{f=1}' file
或者在regexp之后专门化第n条记录的更一般的解决方案(下面的习惯用法“c”):

以下习惯用法描述了如何选择给定要匹配的特定regexp的记录范围:

a) 打印某些regexp中的所有记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
b) 在某些regexp之后打印所有记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
c) 在某些regexp之后打印第n条记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
d) 在某些regexp之后打印除第n条记录以外的每条记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
e) 在一些regexp之后打印N条记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
f) 打印除某些regexp之后的N条记录以外的每条记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
g) 打印某些regexp中的N条记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
我将变量名从“found”的“f”改为“count”的“c”,其中 适当,因为这更能表达变量的实际含义。

切勿使用“模式”一词,因为它非常模糊。始终使用“string”或“regexp”(或shell中的“globbing模式”),无论您真正的意思是什么

您想要的具体答案是:

awk 'f{print;f=0} /regexp/{f=1}' file
或者在regexp之后专门化第n条记录的更一般的解决方案(下面的习惯用法“c”):

以下习惯用法描述了如何选择给定要匹配的特定regexp的记录范围:

a) 打印某些regexp中的所有记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
b) 在某些regexp之后打印所有记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
c) 在某些regexp之后打印第n条记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
d) 在某些regexp之后打印除第n条记录以外的每条记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
e) 在一些regexp之后打印N条记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
f) 打印除某些regexp之后的N条记录以外的每条记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
g) 打印某些regexp中的N条记录:

awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
我将变量名从“found”的“f”改为“count”的“c”,其中
适当,因为这更能表达变量的实际含义。

如果模式匹配,则将下一行复制到模式缓冲区,删除一个返回,然后退出——副作用是打印

sed '/pattern/ { N; s/.*\n//; q }; d'

若模式匹配,将下一行复制到模式缓冲区,删除一个返回,然后退出——副作用是打印

sed '/pattern/ { N; s/.*\n//; q }; d'

我需要打印模式之后的所有行(ok Ed,REGEX),因此我决定使用这一行:

sed -n '/pattern/,$p' # prints all lines after ( and including ) the pattern
但是因为我想打印后面的所有行(并排除模式)

我想在您的案例中,您可以在末尾添加一个
head-1

sed -n '/pattern/,$p' | tail -n+2 | head -1 # prints line after pattern

我需要打印模式之后的所有行(ok Ed,REGEX),因此我决定使用这一行:

sed -n '/pattern/,$p' # prints all lines after ( and including ) the pattern
但是因为我想打印后面的所有行(并排除模式)

我想在您的案例中,您可以在末尾添加一个
head-1

sed -n '/pattern/,$p' | tail -n+2 | head -1 # prints line after pattern

实际上,如果
模式
匹配
连续
行,则
sed-n'/pattern/{n;p}文件名
将失败:

$ seq 15 |sed -n '/1/{n;p}'
2
11
13
15
预期的答案应该是:

2
11
12
13
14
15
我的解决办法是:

$ sed -n -r 'x;/_/{x;p;x};x;/pattern/!s/.*//;/pattern/s/.*/_/;h' filename
例如:

$ seq 15 |sed -n -r 'x;/_/{x;p;x};x;/1/!s/.*//;/1/s/.*/_/;h'
2
11
12
13
14
15
说明:

  • x:在输入的每一行的开头,使用
    x
    命令交换
    模式空间中的内容
    &
    保持空间
  • /{x;p;x}:如果
    模式空间
    (实际上是
    保留空间
    )包含
    (这只是一个
    指示器
    ,指示最后一行是否与
    模式
    匹配),则使用
    x
    当前行
    的实际内容交换到
    模式空间
    ,使用
    p
    打印
    当前行
    ,使用
    x
    恢复此操作
  • x
    :恢复
    图案空间
    保留空间
    中的内容
  • /pattern/!s/*/
    :如果
    当前行
    模式
    不匹配,这意味着我们不应打印下一行,则使用
    s/*/
    命令删除
    模式空间
    中的所有内容
  • /pattern/s/*/
    :如果
    当前行
    模式
    匹配,这意味着我们应该打印下一行,那么我们需要设置一个
    指示器
    告诉
    sed
    打印下一行,因此使用
    s/*/
    模式空间
    中的所有内容替换为
    (第二个命令将使用它来判断最后一行是否与
    模式匹配)
  • h
    :用
    模式空间中的内容覆盖
    保留空间
    ;然后,
    保留空间
    中的内容是
    ^$
    ,这意味着
    当前行
    模式
    匹配,或者
    ^$
    ,这意味着
    当前行
    模式
    不匹配
  • 第五步和第六步不能交换,因为在
    s/*/
    之后,
    模式空间
    不能匹配
    /pattern/
    ,所以必须执行
    s/*/
  • 实际上
    sed-