问题:我想在包含匹配模式的行后面直接打印一行。
我的sed
版本不会采用以下语法(它会在+1p
上轰炸),这似乎是一个简单的解决方案:
sed -n '/ABC/,+1p' infile
我认为awk
会更好地进行多线处理,但我不知道该怎么做。
答案 0 :(得分:118)
永远不要使用“模式”这个词,因为它非常含糊不清。始终使用“string”或“regexp”(或在shell中使用“globbing pattern”),无论你的意思是什么。
您想要的具体答案是:
awk 'f{print;f=0} /regexp/{f=1}' file
或者在regexp(下面的成语“c”)之后专门化第N条记录的更一般的解决方案:
awk 'c&&!--c; /regexp/{c=1}' file
以下习语描述了如何在给定特定正则表达式匹配的情况下选择一系列记录:
a)打印来自某些正则表达式的所有记录:
awk '/regexp/{f=1}f' file
b)在一些正则表达式后打印所有记录:
awk 'f;/regexp/{f=1}' file
c)在一些正则表达式后打印第N条记录:
awk 'c&&!--c;/regexp/{c=N}' file
d)在一些正则表达式后打印除第N条记录以外的每条记录:
awk 'c&&!--c{next}/regexp/{c=N}1' file
e)在一些正则表达式后打印N条记录:
awk 'c&&c--;/regexp/{c=N}' file
f)在一些正则表达式之后打印除N条记录之外的所有记录:
awk 'c&&c--{next}/regexp/{c=N}1' file
g)打印来自某些正则表达式的N条记录:
awk '/regexp/{c=N}c&&c--' file
我将变量名称从“f”更改为“found”到“c”更改为“count” 适当的,因为它更能表达变量实际上是什么。
答案 1 :(得分:35)
之后的行与您感兴趣的匹配,对吗?在sed中,可以这样完成:
sed -n '/ABC/{n;p}' infile
或者,grep的 A 选项可能就是您要找的。 p>
-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
希望有所帮助。
答案 2 :(得分:3)
我需要在模式之后打印所有行(ok Ed,REGEX),所以我选择了这一行:
sed -n '/pattern/,$p' # prints all lines after ( and including ) the pattern
但是因为我想打印所有的线条(并排除图案)
sed -n '/pattern/,$p' | tail -n+2 # all lines after first occurrence of pattern
我想在你的情况下你可以在最后添加head -1
sed -n '/pattern/,$p' | tail -n+2 | head -1 # prints line after pattern
答案 3 :(得分:2)
awk版本:
awk '/regexp/ { getline; print $0; }' filetosearch
答案 4 :(得分:1)
如果模式匹配,将下一行复制到模式缓冲区,删除一个返回,然后退出 - 副作用就是打印。
sed '/pattern/ { N; s/.*\n//; q }; d'
答案 5 :(得分:1)
如果sed -n '/pattern/{n;p}' filename
匹配pattern
行,continuous
实际上会失败:
$ 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
命令交换pattern space
&中的内容。 hold space
。/_/{x;p;x};
:如果pattern space
实际上是hold space
,则包含_
(这只是indicator
,表示最后一行是否与{{{1}匹配1}}或者没有),然后使用pattern
将x
的实际内容交换为current line
,使用pattern space
打印p
,{{1恢复此操作。 current line
:恢复x
和x
。pattern space
:如果hold space
与/pattern/!s/.*//
不匹配,这意味着我们不应该打印下一行的NEXT,然后使用current line
命令删除pattern
中的所有内容1}}。s/.*//
:如果pattern space
与/pattern/s/.*/_/
匹配,这意味着我们应该打印下一行的NEXT,那么我们需要设置current line
来告诉pattern
要打印NEXT行,请使用indicator
将sed
中的所有内容替换为s/.*/_/
(第二个命令将使用它来判断最后一行是否与pattern space
匹配)。_
:使用pattern
中的内容覆盖h
;那么,hold space
中的内容为pattern space
,这意味着hold space
与^_$
或current line
匹配,这意味着pattern
与^$
不匹配{1}}。current line
之后,pattern
无法与s/.*/_/
匹配,因此必须执行pattern space
!答案 6 :(得分:1)
这可能适合你(GNU sed):
sed -n ':a;/regexp/{n;h;p;x;ba}' file
使用seds grep-like选项-n
,如果当前行包含所需的正则表达式,则将当前行替换为下一行,将该行复制到保留空间(HS),打印行,交换模式空间(PS)为HS并重复。
答案 7 :(得分:0)
通过一些抓取就可以做到这一点(它在POSIX shell中和BusyBox下运行):
cat my-file | grep -A1 my-regexp | grep -v -- '--' | grep -v my-regexp
-v
将显示不匹配的行