如何从匹配条件之间的文件中提取文本的一部分

如何从匹配条件之间的文件中提取文本的一部分

我有一个如下文件。

~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。我怎么才能得到它?我正在研究awksed但找不到任何选择。

答案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

如果您有GNUawk,您可以使用特殊变量恢复记录分隔符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 行

参考: 用于多行搜索的正则表达式 (grep)

相关内容