gawk는 두 개의 TSV를 열별로 조인합니다(SQL 조인).

gawk는 두 개의 TSV를 열별로 조인합니다(SQL 조인).

TSV 파일을 추가하는 방법, 예:

TSV

c   7   r   z
d   6   s   w
f   1   f   f
b   8   p   y
a   9   q   x

TSV

a   q   a
c   r   ccc
b   p   bb
0   0   0
d   s   dddd

where a$1,a$3==b$1,b$2여기서는 열 단위로 "결합" 하고 나머지 (a$2,a$4,b$3)를 표시하고 싶습니다 .

6   w   dddd
9   x   a
8   y   bb
7   z   ccc

문제는 gawk에서 이것을 어떻게 하시겠습니까?

줄의 순서가 요구 사항을 충족하지 않습니다.(출력에서. 입력에서 행의 순서는 정의되지 않았으며 a.tsv 및 b.tsv에서 다를 수 있습니다. 관계형 데이터베이스의 행과 마찬가지로 순서가 없습니다.)

고유성 설명key={a$1,a$3}:처음에는 " .As 의 고유성"을 가정했습니다.글렌 잭맨참고 - 키를 기반으로 고유한 행을 허용하지 않으므로 원래 문제 설명에서 가정할 수 없습니다. 감사합니다.글렌.

답변1

join이 명령은 하나의 필드만 추가할 수 있는 것 같습니다 .1,2], 그래서:

awk '
    BEGIN {FS=OFS="\t"}
    NR==FNR {a[$1 FS $3] = $2 FS $4; next}
    $1 FS $2 in a {print a[$1 FS $2], $3}
' a.tsv b.tsv

의견으로 인한 업데이트: 주어진 키가 고유하지 않기 때문에 "a.tsv"에서 여러 항목을 작성하는 기술이 있습니다.

awk '
    BEGIN {FS=OFS="\t"}
    NR==FNR {
        key = $1 FS $3
        if (key in a)
            a[key] = a[key] "\n" $2 FS $4
        else
            a[key] = $2 FS $4
        next
    }
    $1 FS $2 in a {
        split(a[$1 FS $2], ary, /\n/)
        for (idx in ary)
            print ary[idx], $3
    }
' a.tsv b.tsv

답변2

나는 작업을 두 개의 다른 프로그램으로 나누었습니다.

  1. 사용가입(1)두 파일 연결

  2. 어크(1)또는절단(1)불필요한 열 제거

답변3

잘은 모르겠지만 awk텍스트 파일의 필드를 처리하기 위해 특별히 설계되었기 때문에 작업이 잘 될 것이라고 생각했지만 (? join)ktf설명), 여기에 표준 유닉스 도구를 사용하는 솔루션이 있습니다: joinand cutand pasteand sort-- 많은 "and"가 있지만 작동하며 awk왜 더 나은지에 대한 예 역할을 합니다 :)... 주로 방법에 대해 넣었습니다. 비교 요소 .

join -t $'\t' -o 1.2 1.3  2.2  \
 <(paste <(paste <(cut -f1 a.tsv) \
                 <(cut -f3 a.tsv) \
                 | tr '\t' '\0' ) \
         <(cut -f2 a.tsv) \
         <(cut -f4 a.tsv) \
         | sort ) \
 <(paste <(paste <(cut -f1 b.tsv) \
                 <(cut -f2 b.tsv) \
                 | tr '\t' '\0' ) \
         <(cut -f3 b.tsv) \
         | sort ) 

답변4

마침내 나는 그것을 할 수 있었다. 그래서 내 솔루션을 공유합니다.

awk '
BEGIN {
    FS=OFS="\t"
    while ((getline < "a.tsv") > 0){
        a2[$1,$3] = $2; a4[$1,$3] = $4
    }
}
($1,$2) in a2 { print a2[$1,$2] FS a4[$1,$2] FS $3 }' < b.tsv

생산하다:

9   x   a
7   z   ccc
8   y   bb
6   w   dddd

이 솔루션은 다음과 같습니다.

  • 입력 라인의 순서를 가정하지 않습니다.
  • 일부 줄에 다른 파일과 일치하는 항목이 없을 때 작동합니다.
  • 다음 행은 다음 a.tsv과 같다고 가정합니다.key = {a$1,a$3}

관심있는 분들을 위해오른쪽 가입if( ($1,$2) in a2), 명세서를 삭제하면 됩니다 . 관심있는 분들을 위해왼쪽 조인, "올바른 조인" 버전을 수행하고 a.tsv를 b.tsv로 바꾸십시오(그리고 이에 따라 코드를 변경하십시오).

고유성 설명: 처럼글렌 잭맨a.tsv따르면 이 줄은 고유하지 않을 수 있으므로 key={a$1,a$3}그의 솔루션을 확인하고 싶을 수도 있습니다.

관련 정보