gawk 按列连接两个 TSV(a'la sql join)

Grz*_*cki 2 awk csv

如何加入,到 tsv 文件,示例:

a.tsv

c   7   r   z
d   6   s   w
f   1   f   f
b   8   p   y
a   9   q   x
Run Code Online (Sandbox Code Playgroud)

b.tsv

a   q   a
c   r   ccc
b   p   bb
0   0   0
d   s   dddd
Run Code Online (Sandbox Code Playgroud)

在这里,我想按列“加入”它们,where a$1,a$3==b$1,b$2并显示 rest (a$2,a$4,b$3) :

6   w   dddd
9   x   a
8   y   bb
7   z   ccc
Run Code Online (Sandbox Code Playgroud)

问题是:你会如何在 gawk 中做到这一点?

行的顺序不满足(在输出中。在输入中,行的顺序未定义,并且在 a.tsv 和 b.tsv 中可以不同 - 就像关系数据库中的行一样,它们没有顺序)。

唯一注:本来,我以为“的独特key={a$1,a$3}作为,格伦·杰克曼发现-它不能从原来的问题陈述假定,因为它允许不按任何键唯一行-感谢格伦

gle*_*man 6

看来该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
Run Code Online (Sandbox Code Playgroud)

由于评论而更新:由于给定的键不是唯一的,这是一种从“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
Run Code Online (Sandbox Code Playgroud)