설명하다

설명하다

다음과 같은 텍스트 파일이 있습니다.

Doc_A 123 abc
Doc_A 456 def
Doc_A 789 ghi
Doc_B 123 abc
Doc_B 456 def
Doc_C 123 abc
Doc_C 456 def
Doc_C 789 ghi
Doc_C 101 jkl

및 참고 문서

Doc_A
Doc_B
Doc_C
Doc_D
Doc_E
Doc_F

참조 파일의 이름과 일치하는 텍스트 파일의 첫 번째 줄을 추출하고 해당 줄을 인쇄하거나, 일치하는 항목이 없으면 다음과 같이 특정 고정 패턴을 인쇄하고 싶습니다.

Doc_A 123 abc
Doc_B 123 abc
Doc_C 123 abc
Doc_D 10 20
Doc_E 10 20
Doc_F 10 20

아래와 같이 awk를 사용하여 일치하는 패턴을 인쇄할 수 있습니다. 요구 사항에 따라 고정된 방식으로 찾을 수 없는 패턴을 어떻게 인쇄할 수 있습니까?

awk 'FNR == NR { a[$1] = 0; } FNR != NR { for (i in a) if ($0 ~ i && a[i]++ == 0) { print $0; break; } }' \ref.txt file.txt

답변1

일치하는 항목을 조회 배열에서 제거한 다음 끝에 남은 항목을 인쇄하는 것은 어떻습니까?

$ awk 'NR==FNR {a[$1]; next} 
  $1 in a {print; delete a[$1]} 
  END {for (i in a) print i, "10 20"}
' ref.txt file.txt
Doc_A 123 abc
Doc_B 123 abc
Doc_C 123 abc
Doc_D 10 20
Doc_E 10 20
Doc_F 10 20

(awk는 배열 순회 순서를 보장하지 않습니다. 문제가 있는 경우)

설명하다

그 동안 NR==FNR우리는 첫 번째 명명된 파일( ref.txt)에 대해 작업하고 있습니다. 첫 번째(이 경우 고유한) 필드로 색인이 지정된 배열 항목을 만든 다음 레코드로 이동합니다 next. 배열 요소에 값을 할당할 필요가 없습니다.

그렇지 않으면 두 번째 명명된 파일( )을 처리 중입니다 file.txt. 첫 번째 열이 참조 파일에서 구성한 배열과 일치하는지 확인하고 a일치하면 레코드를 인쇄합니다. $0그런 다음 항목을 삭제합니다.

제거는 두 가지 목적으로 사용됩니다. 다음에 $1 in a동일한 항목을 테스트할 때 $1대답은 거짓이 되기 때문에 일치 항목을 "고유하게" 합니다. 이는 또한 file.txt모든 행이 처리된 후에도 의 나머지 요소가 a아직 일치하지 않음을 의미합니다. END이를 블록의 "고정" 형식으로 인쇄할 수 있습니다.

답변2

작업에 awk가 필요합니까? grep도 가능.

파일이 공백으로 구분된 것 같습니다. 아래 솔루션은 참조 파일의 고정 패턴에 공백이 포함되지 않는다는 가정을 기반으로 합니다.

file.txt텍스트 파일을 ref.txt.

$ for P in $(cat ref.txt); do grep -m1 "^$P[[:blank:]]" file.txt || printf "%s 10 20\n" "$P"; done
Doc_A 123 abc
Doc_B 123 abc
Doc_C 123 abc
Doc_D 10 20
Doc_E 10 20
Doc_F 10 20

답변3

다음과 같은 다양한 방법으로 이 작업을 수행할 수 있습니다.

awk '
 NR == FNR && !($1 in a){a[$1]=$0}
 NR != FNR{print ($1 in a) ? a[$1] : $1" 10 20"}
' inp ref.txt


perl -lane '
  $h{$F[0]} = $_ unless exists $h{$F[0]}}{
  while ( <STDIN> ) {
     chomp;
     print(exists $h{$_} ? $h{$_} : qq<$_ 10 20>);
   }
' inp < ref.txt


while IFS= read -r a
do
   grep -m1 -F -- "$a" inp || echo "$a 10 20"
done < ref.txt

결과:

Doc_A 123 abc
Doc_B 123 abc
Doc_C 123 abc
Doc_D 10 20
Doc_E 10 20
Doc_F 10 20

관련 정보