awk를 사용하여 다른 파일의 내용을 기반으로 한 파일에서 데이터를 추출하는 방법은 무엇입니까?

awk를 사용하여 다른 파일의 내용을 기반으로 한 파일에서 데이터를 추출하는 방법은 무엇입니까?

두 개의 파일이 있습니다. 파일에는 구조화된 데이터가 포함되어 있습니다. 아래는 그 예입니다.

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

관련 정보