我有两个文件。一个文件包含结构化数据,下面是一个示例。
article 1 title
article 1 body line 1
article 1 body line 2
+++
article 2 title
article 2 body line 1
article 2 body line 2
article 2 body line 3
+++
article 3 title
article 3 body line 1
article 3 body line 2
+++
article 4 title
article 4 body line 1
article 4 body line 2
article 4 body line 3
如您所见,+++
是记录的分隔符。对于每条记录,第一行是标题,所有其他行都是该记录的内容。另一个文件是一个带有标题列表的简单文本文件。例如:
article 1 title
article 3 title
article 4 title
我想要的是第二个文件中列出标题的记录。所以对于前面提到的例子,预期的结果是:
article 1 title
article 1 body line 1
article 1 body line 2
+++
article 3 title
article 3 body line 1
article 3 body line 2
+++
article 4 title
article 4 body line 1
article 4 body line 2
article 4 body line 3
我认为awk
可能可以解决我的问题,但我不知道如何解决。
我尝试过的是这样的:
awk 'BEGIN{RS="(\r?\n)?\+{3}(\r?\n)?"; FS="\r?\n"; ORS="+++"} NR==FNR{a[$0];next} ...' title_list.txt data.txt
我的问题是这RS
两个文件的 应该不同,我不知道如何使其工作。
答案1
您可以为每个文件单独设置 RS 等变量。例如:
$ awk 'NR==FNR{a[$0];next} $1 in a' RS='\r?\n' title_list.txt RS='+++\r?\n' FS='\r?\n' ORS='+++\n' data.txt
article 1 title
article 1 body line 1
article 1 body line 2
+++
article 3 title
article 3 body line 1
article 3 body line 2
+++
article 4 title
article 4 body line 1
article 4 body line 2
article 4 body line 3
+++
答案2
您gawk
可以使用特殊块BEGINFILE
并ENDFILE
在读取新文件之前/之后设置您需要的任何规则,例如:
$ awk 'NR==FNR{a[$0]++;next}ENDFILE{RS="+++\n";FS="\n"}a[$1]{printf $0RT}' title_list.txt data.txt
article 1 title
article 1 body line 1
article 1 body line 2
+++
article 3 title
article 3 body line 1
article 3 body line 2
+++
article 4 title
article 4 body line 1
article 4 body line 2
article 4 body line 3
答案3
通过以下方法使用 sed 和 awk 组合完成
命令
k=`awk '{print NR}' file2| sed -n '$p'`
for ((i=1;i<=$k;i++)); do j=`awk -v i="$i" 'NR==i{print $0}' file2`; sed -n "/$j/,/+++/p" file1; done
output
for ((i=1;i<=$k;i++)); do j=`awk -v i="$i" 'NR==i{print $0}' file2`; sed -n "/$j/,/+++/p" file1; done
article 1 title
article 1 body line 1
article 1 body line 2
+++
article 3 title
article 3 body line 1
article 3 body line 2
+++
article 4 title
article 4 body line 1
article 4 body line 2
article 4 body line 3