다음과 같이 비교적 작은 공백으로 구분된 파일이 있습니다(그러나 많은 열과 행이 있음).
파일 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)
모든 문제는 join
file2 처리 및 옵션과 관련이 있습니다.
- file2는 필드 1(필드 2여야 함)을 기준으로 정렬됩니다.
-t '<tab>'
options가 없으면join
file2는 탭으로 구분됩니다.join
file2 필드 2를 결합하는 옵션이 누락되었습니다 .- file2의 필드가 정확하더라도
join
기본 출력은 연결된 필드를 먼저 인쇄하므로-o FORMAT
에 옵션을 지정해야 합니다join
. - file2 헤더는 제거되지 않습니다.
- 문제를 일으키지는 않지만 처리가 필요하지 않습니다. 첫 번째 줄을 건너뛸 수 있으므로
tail
file1에는 필요하지 않습니다 .awk
-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