gawkは2つのTSVを列ごとに結合します(SQL結合)。

gawkは2つの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つのフィールドしか追加できないようです。12]、だから:

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

私は仕事を2つの異なるプログラムに分けました。

  1. 使用参加(1)2つのファイルの関連付け

  2. アーク(1)または切断(1)不要な熱を除去

答え3

よくわかりませんが、awkテキストファイルのフィールドを処理するように特別に設計されているので、うまくいくと思いましたが(?joinktf説明)、ここに標準のUnixツールを使用するソリューションがあります。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}彼の解決策を確認したいと思うかもしれません。

関連情報