더 작은 파일과 더 큰 파일 사이에서 일치하는 값과 일치하지 않는 값을 병합하여 인쇄합니다.

더 작은 파일과 더 큰 파일 사이에서 일치하는 값과 일치하지 않는 값을 병합하여 인쇄합니다.

다음과 같이 비교적 작은 공백으로 구분된 파일이 있습니다(그러나 많은 열과 행이 있음).

파일 1:

Entry1
a
b
c
d

다음과 같이 한 줄에 많은 중복 항목이 있는 또 다른 거대한 탭으로 구분된 파일입니다.

파일 2:

value       ID1   ID2   
1      a    aaaa1
1      a    aaaa2
1      b    bbbb1
1      b    bbbb2
1      b    bbbb3
1      d    aaaa4

먼저 아래와 같이 file1의 각 항목과 file2의 ID1 필드(열 2) 간의 일치 항목을 지정하여 file1과 동일한 크기의 탭으로 구분된 파일을 인쇄하려고 합니다.이건 별개의 질문이에요:

Entry1
a
b
NoMatch
d

또한 file1과 file2의 값을 포함하는 병합된 탭으로 구분된 파일을 인쇄합니다. 이번에는 file2에 중복된 항목이 있지만 다음과 같이 NoMatch도 유지합니다.

value       ID1   ID2   
1      a    aaaa1
1      a    aaaa2
1      b    bbbb1
1      b    bbbb2
1      b    bbbb3
NoMatch NoMatch NoMatch
1      d    aaaa4

Join 명령을 사용하려고 하면 NoMatch 메시지가 나타납니다.

join -a1 -e "NoMatch" <(awk -F ' ' '{print $0}' file1.txt |tail -n +2|sort -k1,1) <(cat file2 | sort -k1,1) > out.txt

하지만 이것은 file1의 모든 내용을 인쇄하기 때문에 뭔가 잘못하고 있는 것 같습니다. 그러나 file2에 일치하는 항목이 없으면 나머지 필드는 비어 있습니다(따라서 "NoMatch" 메시지가 표시되지 않음). 제가 어떤 사람인지 이해하는 데 도움을 주실 수 있나요? 뭔가 잘못했나요?

매우 감사합니다!

#

Giles님, 감사합니다. 방금 가입했기 때문에 귀하의 의견에 답변할 수 없는 것 같습니다...귀하의 제안은 다음과 같습니다.

join -a1 -e "NoMatch" -11 -22 --header -o2.1,2.2,2.3 file1 file2

두 번째 쿼리 Output2를 해결했습니다. 감사합니다! file1과 동일한 줄이 있는 첫 번째 Output1을 얻는 방법을 물어봐도 될까요? 다시 한 번 감사드립니다! !

don_crissti의 도움으로 다음과 같은 두 번째 출력을 얻을 수 있습니다.

paste -d'\t' file2 <(awk 'FNR==NR{seen[$1]++; next}  {(FNR==1 || ($1 in seen)) || $1="NoMatch"};1'  file2  file1)

답변1

가독성을 높이기 위해 원본 예제의 형식을 다시 지정합니다.

join -a1 -e "NoMatch" \
 <(awk -F ' ' '{print $0}' file1.txt |tail -n +2|sort -k1,1) \
 <(cat file2 | sort -k1,1)

모든 문제는 joinfile2 처리 및 옵션과 관련이 있습니다.

  1. file2는 필드 1(필드 2여야 함)을 기준으로 정렬됩니다.
  2. -t '<tab>'options가 없으면 joinfile2는 탭으로 구분됩니다.
  3. joinfile2 필드 2를 결합하는 옵션이 누락되었습니다 .
  4. file2의 필드가 정확하더라도 join기본 출력은 연결된 필드를 먼저 인쇄하므로 -o FORMAT에 옵션을 지정해야 합니다 join.
  5. file2 헤더는 제거되지 않습니다.
  6. 문제를 일으키지는 않지만 처리가 필요하지 않습니다. 첫 번째 줄을 건너뛸 수 있으므로 tailfile1에는 필요하지 않습니다 .awk
  7. -F ' '옵션이 필요하지 않습니다 awk.

이러한 문제를 수정하면 다음과 같은 결과가 발생합니다.

#!/bin/bash
head -1 file2
join -t '   ' -2 2 -a 1 -e NoMatch -o 2.1,2.2,2.3 \
 <(awk 'NR==1{next} {print $0}' file1.txt | sort) \
 <(tail -n +2 file2 | sort -k2)

그러면 탭으로 구분된 다음과 같은 출력이 생성됩니다.

value   ID1     ID2
1       a       aaaa1
1       a       aaaa2
1       b       bbbb1
1       b       bbbb2
1       b       bbbb3
NoMatch NoMatch NoMatch
1       d       aaaa4

관련 정보