한 필드에 두 파일 결합

한 필드에 두 파일 결합

두 파일을 비교해야 하며 비교 결과에 따라 첫 번째 파일에 새 열을 추가해야 합니다. C 열은 기본 키입니다..

A,B,C,D
1,1990,I001,2473264
2,1991,I002,2473265
3,1992,I004,2473266
4,1993,6050,912432
5,1994,6003,912433

두 번째 파일

A,B
I001,2.3 GHz
I002,2.3 GHz
I004,2.3 GHz
6050,1.8 GHz
6003,850 MHz

예상 출력

A,B,C,D,E
1,1990,2.3 GHz,I001,2473264
2,1991,2.3 GHz,I002,2473265
3,1992,2.3 GHz,I004,2473266
4,1993,1.8 GHz,6050,912432
5,1994,850 MHz,6003,912433

이 코드는 제대로 작동하지만 레코드가 일치하지 않으면 첫 번째 파일의 줄을 건너뜁니다. 하지만 건너뛰고 해당 열에 0 또는 NA를 추가하는 것을 원하지 않습니다.

awk -F, 'NR==FNR{a[$1]=$2;next}a[$3]{print $0","a[$3]}' test2 test1
A,B,C,D
1,1990,I001,2473264
2,1991,I002,2473265
3,1992,I004,2473266
4,1993,6050,912432
5,1994,6003,912433
6,1995,6004,21234

예상 출력:

1,1990,I001,2473264,2.3 GHz
2,1991,I002,2473265,2.3 GHz
3,1992,I004,2473266,2.3 GHz
4,1993,6050,912432,1.8 GHz
5,1994,6003,912433,850 MHz
6,1995,6004,21234,0

답변1

awk다음으로 변경하세요 .

$ awk -F, 'NR==FNR{a[$1]=$2;next} FNR!=1{print $0","(a[$3]?a[$3]:"NA")}' SECOND FIRST
1,1990,I001,2473264,2.3 GHz
2,1991,I002,2473265,2.3 GHz
3,1992,I004,2473266,2.3 GHz
4,1993,6050,912432,1.8 GHz
5,1994,6003,912433,850 MHz
6,1995,6004,21234,NA

처음으로 원하는 결과를 얻으려면:

$ awk -F, 'NR==FNR{a[$1]=$2;next} FNR!=1{$3=(a[$3]?a[$3]:"NA")","$3; print}' OFS=, SECOND FIRST
1,1990,2.3 GHz,I001,2473264
2,1991,2.3 GHz,I002,2473265
3,1992,2.3 GHz,I004,2473266
4,1993,1.8 GHz,6050,912432
5,1994,850 MHz,6003,912433
6,1995,NA,6004,21234

답변2

awk귀하의 프로그램을 다음과 같이 수정하면 올바른 것입니다.무조건사용

print $0","( a[$3] ? a[$3] : 0 )

사용하는 대신

print $0","a[$3]

a[$3]0이 아니거나 비어 있는 경우 . 즉, a[$3]필드가 0이거나 비어 있으면 0을 사용하고, 그렇지 않으면 를 사용합니다 a[$3].

다시 말해서,

awk -F, -v OFS=',' 'FNR==NR { a[$1]=$2; next } FNR > 1 { print $0, (a[$3] ? a[$3] : 0) }' fileB fileA

FNR > 1여기서는 헤더를 건너뛰는 데 사용합니다 .


사용 join:

$ join -t , -1 3 -o 1.1,1.2,1.3,1.4,2.2 fileA fileB
1,1990,I001,2473264,2.3 GHz
2,1991,I002,2473265,2.3 GHz
3,1992,I004,2473266,2.3 GHz
4,1993,6050,912432,1.8 GHz
5,1994,6003,912433,850 MHz

파일이 조인 키로 정렬되지 않은 경우(프로세스 대체를 지원하는 셸에서):

$ join -t , -1 3 -o 1.1,1.2,1.3,1.4,2.2 <( sort -t, -k3,3 fileA ) <( sort fileB )
5,1994,6003,912433,850 MHz
4,1993,6050,912432,1.8 GHz
1,1990,I001,2473264,2.3 GHz
2,1991,I002,2473265,2.3 GHz
3,1992,I004,2473266,2.3 GHz

작업은 두 파일 모두에서 수행됩니다 join. 쉼표가 필드 구분 기호임을 INNER JOIN알려줌으로써 -t ,세 번째 필드를 첫 번째 파일의 조인 키로 선택합니다( 해당 파일에서 동일한 다른 필드를 사용하지 않는 한 두 번째 파일의 첫 번째 필드가 키라고 가정 ).join-1 3-2 NN

-o플래그는 join출력에 포함할 필드와 파일( x.y파일의 열을 나타냄)을 알려줍니다.yx

join매우 빠른 작업이지만필요입력 파일은 조인 키를 기준으로 정렬됩니다(위의 첫 번째 예를 볼 수 있는 행운이 있었습니다). 위 두 번째 예의 최종 출력은 정렬되지 않았습니다.첫 번째필드이지만 파이프를 통해 쉽게 해결할 수 있습니다 sort -k1,1n.


두 번째 경우에는 불일치로 인해

$ join -t, -1 3 -o1.1,1.2,1.3,1.4,2.2 -a 1 -e 0  <( sort -t, -k3,3 fileA ) <( sort fileB )
5,1994,6003,912433,850 MHz
6,1995,6004,21234,0
4,1993,6050,912432,1.8 GHz
A,B,C,D,0
1,1990,I001,2473264,2.3 GHz
2,1991,I002,2473265,2.3 GHz
3,1992,I004,2473266,2.3 GHz

추가함으로써 첫 번째 파일의 모든 필드가 항상 출력되고 두 번째 파일의 각 누락된 필드에 0이 삽입되도록 -a 1 -e 0요청합니다 .join(-a 1

보시다시피 이제 올바른 결과를 얻었지만 (우리가 요청했기 때문에) 첫 번째 파일의 헤더도 포함했습니다. 두 파일의 데이터에서 헤더를 제거하고 결과를 정렬하려면 다음을 수행하십시오.

$ join -t, -1 3 -o1.1,1.2,1.3,1.4,2.2 -e 0 -a1  <( tail -n +2 fileA | sort -t, -k3,3 ) <( tail -n +2 fileB | sort ) | sort -k1,1n
1,1990,I001,2473264,2.3 GHz
2,1991,I002,2473265,2.3 GHz
3,1992,I004,2473266,2.3 GHz
4,1993,6050,912432,1.8 GHz
5,1994,6003,912433,850 MHz
6,1995,6004,21234,0

이 명령은 실제로 두 상황 모두에 적용됩니다.

답변3

사용암소 비슷한 일종의 영양 join확장된 데이터와첫 번째echo헤더를 대체하기 위한 출력 형식 tail( join일관되지 않은 헤더로 인해 혼동될 수 있으므로):

echo A,B,C,D,E
join -t ',' --header --nocheck-order test1 test2 \
     -a 1 -e NA -1 3 -2 1 -o 1.1,1.2,2.2,1.3,1.4 | tail -n +2

산출:

A,B,C,D,E
1,1990,2.3 GHz,I001,2473264
2,1991,2.3 GHz,I002,2473265
3,1992,2.3 GHz,I004,2473266
4,1993,1.8 GHz,6050,912432
5,1994,850 MHz,6003,912433
6,1995,NA,6004,21234

관련 정보