假设我有一个文件:
Line 1
Line 2
Start Line 3
Line 4
Line 5
Line 6
End Line 7
Line 8
Line 9
Start Line 10
Line 11
End Line 12
Line 13
Start line 14
Line 15
仅当找到sed
和/Start/
时,我才想使用/End/
在模式之间进行打印。
sed -n '/Start/,/End/p'
按预期工作,如果您知道两个标记都在预期的顺序,但只是Start
从End
打印到文件的末尾订购或不订购。 (即,在示例中打印第14行和第15行)
我试过了:
sed -n '/Start/,/End/{H;}; /End/{x; p;}' file
打印:
# blank line here...
Start Line 3
Line 4
Line 5
Line 6
End Line 7
End Line 7
Start Line 10
Line 11
End Line 12
虽然接近但有两个问题:
我希望得到类似于
的结果$ awk '/Start/{x=1} x{buf=buf$0"\n"} /End/{print buf; buf=""; x=0}' file
Start Line 3
Line 4
Line 5
Line 6
End Line 7
Start Line 10
Line 11
End Line 12
(不需要块之间的空行......)
答案 0 :(得分:2)
使用来自Solaris 11的GNU sed和sed:
sed -n '/Start/{h;b;};H;/End/{g;p;}' file
输出:
Start Line 3 Line 4 Line 5 Line 6 End Line 7 Start Line 10 Line 11 End Line 12
如果找到Start
复制当前模式空间以保留空间(h
)并跳转到脚本末尾(b
)。对于每隔一行追加当前模式空间来保留空间(H
)。如果找到End
,则将保留空间复制回模式空间(g
),然后打印模式空间(p
)。
答案 1 :(得分:1)
你可以使用这个awk:
awk 'x{buf=buf ORS $0} /Start/{x=1; buf=$0} /End/{print buf; buf=""; x=0}' file
Start Line 3
Line 4
Line 5
Line 6
End Line 7
Start Line 10
Line 11
End Line 12
这是一个sed
版本,可以在OSX(BSD)sed
(Based on Benjamin's sed command)上执行相同操作:
sed -n -e '/Start/{:a;' -e 'N;/End/!ba;' -e 'p;}' file
答案 2 :(得分:1)
GNU sed:遇到Start
后,只要我们看不到End
,就要继续添加行;一旦我们这样做,打印模式空间并重新开始:
$ sed -n '/Start/{:a;N;/End/!ba;p}' infile
Start Line 3
Line 4
Line 5
Line 6
End Line 7
Start Line 10
Line 11
End Line 12
获取块之间的换行是很棘手的。这将在每个块之后添加一个,但最后会产生额外的空白:
$ sed -n '/Start/{:a;N;/End/!ba;s/$/\n/p}' infile
Start Line 3
Line 4
Line 5
Line 6
End Line 7
Start Line 10
Line 11
End Line 12
[blank]
答案 3 :(得分:0)
就个人而言,我更喜欢你的awk解决方案,但是:
sed -n -e '/start/,/end/H' -e '/end/{s/.*//; x; p}' input