我有一个如下文件。
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
~PAR2~
This is Par2 line 1
This is Par2 line 2
Par Finished
如果我通过了PAR1
,我应该得到PAR1
和之间的所有线Par Finished
。我怎么才能得到它?我正在研究awk
,sed
但找不到任何选择。
答案1
如果你想要页眉和页脚行那么这很简单,sed
例如
sed -n "/^~PAR1~$/,/Par Finished/p"
这与变量一起使用很简单
START=PAR1
sed -n "/^~$START~$/,/Par Finished/p"
我们还可以将最后一行设为变量
START=PAR1
END="Par Finished"
sed -n "/^~$START~$/,/$END/p"
结果如下:
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
现在,如果您不需要开始/结束行并且不需要空白行,那么情况会稍微复杂一些。
可能有更好的方法,但这对我有用:
sed -n "/^~$START~$/,/$END/ { /^~$START~$/d ; /$END/d ; /^$/d ; p }"
这样做的结果是
This is Par1 line 1
This is Par1 line 2
答案2
您可以使用该Par Finished
行(带有可选的尾随空白行)作为记录分隔符(然后替换它以完成记录)
awk -vRS='\nPar Finished\n*' -vp='PAR1' '$0 ~ p {print $0,"\nPar Finished"}' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
如果您有GNU
awk,您可以使用特殊变量恢复记录分隔符RT
(如果您愿意,可以删除额外的换行符)
gawk -vRS='\nPar Finished\n*' -vp='PAR1' '$0 ~ p {sub("\n*$", "", RT); print $0,RT}' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
当然如果你不需要通过多变的 Par1
你使用一个简单的正则表达式范围
awk '/PAR1/,/Par Finished/' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
答案3
对于足够小的文件grep
输入pcre
$ s="PAR1"
$ grep -oPz "(?s)[^\n]*${s}.*?\n.*?Par Finished.*?\n" ip.txt
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
要获取图案之间的线条:
$ grep -oPz "(?s)${s}.*?\n\K.*?(?=Par 完成)" ip.txt 这是 Par1 第 1 行 这是 Par1 第 2 行
将变量更改为PAR2
$s=“PAR2” $ grep -oPz "(?s)${s}.*?\n\K.*?(?=Par 完成)" ip.txt 这是 Par2 第 1 行 这是 Par2 第 2 行