我有一个包含以下信息的文件:
start pattern1
line1
line2
...
end pattern1
line3
line4
start pattern2
...
我的输出应该是:
start pattern1
line1
line2
end pattern1
如果我知道pattern1
是什么,我可以做
sed '/start pattern1/,/end pattern1/p' <file>
但是在这里,我希望匹配pattern1
(如perl正则表达式中的\S+
)并最终使用相同的内容(如$1
)。我怎么能这样做?
答案 0 :(得分:4)
使用Perl中的range operator,不会同时测试模式
do
更新为评论中指定的实际模式。
我使用捕获进行测试(在print
块中而不仅仅是...
)并且它有效,但问题可能在于等待是否有其他捕获。如果你不捕获任何其他正则表达式中的任何东西,这都有效。
请注意,使用..
代替{{1}},不测试正确的操作数,直到下次评估。
答案 1 :(得分:1)
使用awk在pattern1
s(包括)之间打印:
$ awk '/pattern1/{p=!p;print;next} p' file
pattern1
line1
line2
...
pattern1
可以更好地定义正则表达式,例如/^pattern1$/
或$0=="pattern1"
。
答案 2 :(得分:1)
这可能适合你(GNU sed):
sed -n '/pattern/,//p' file
这会调用一个触发器匹配的范围,空//
匹配最后一个正则表达式。 p
在范围切换为真时打印所有内容。
N.B。 -n
调用类似于grep的性质并关闭自动打印。
替代方案:
sed '/pattern/!d;:a;n;//!ba' file
答案 3 :(得分:0)
尝试使用awk解决方案,并告诉我这是否对您有所帮助。
awk -v RS="" '{match($0,/start pattern1.*start pattern1/);print substr($0,RSTART,RLENGTH)}' Input_file
编辑: OP没有显示像Input_file也可能有空行,根据CWLiu,我添加了一个建议,如果有任何空行也可以。
awk '/start pattern1/{print;getline;while($0 !~ /start pattern1/){print;getline};print}' Input_file
答案 4 :(得分:0)
所以,这里的awk
实施基于对您问题的替代解释(因为它不太清楚)。
如果要检测以pattern1
开头的第一行中的start
,然后将每行打印到end pattern1
,您可以这样做:
$ awk '/^start / {pat=$2; next} /^end / && $2~pat {exit} {print}' file
line1
line2
...