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つのフィールドしか追加できないようです。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
私は仕事を2つの異なるプログラムに分けました。
使用参加(1)2つのファイルの関連付け
アーク(1)または切断(1)不要な熱を除去
答え3
よくわかりませんが、awk
テキストファイルのフィールドを処理するように特別に設計されているので、うまくいくと思いましたが(?join
)ktf説明)、ここに標準のUnixツールを使用するソリューションがあります。join
and cut
and paste
and 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}
彼の解決策を確認したいと思うかもしれません。