web-dev-qa-db-ja.com

最初の列に基づいて、重複する行のない2つのファイルをソートおよびマージします

すべてのテスト名を含むファイルがあります:

$ cat all_tests.txt
test1
test2
test3
test4
test5
test6

そして、テスト名と関連する結果を含む別のファイル:

$ cat completed_tests.txt
test1 Passed
test3 Failed
test5 Passed
test6 Passed

関連する結果を持つすべてのテスト名と重複なしの新しいファイルを作成する方法は?

私が実行した場合:

sort all_tests.txt completed_tests.txt

出力には重複が含まれます。

test1 
test1 Passed
test2
test3 
test3 Failed
test4
test5 
test5 Passed
test6 
test6 Passed

目的の出力:

test1 Passed
test2
test3 Failed
test4
test5 Passed
test6 Passed
12
Benny

ファイルが両方ともソートされていれば、joinでこれを簡単に達成できるようです。

$ join -a 1 all_test.txt completed_test.txt
test1 Passed
test2
test3 Failed
test4
test5 Passed
test6 Passed

-a 1は、何も結合されていないファイル1の行を印刷することを意味します。

ファイルがまだソートされていない場合、これを使用できます(terdonに感謝!):

join -a 1  <(sort all_tests.txt) <(sort completed_tests.txt )
17
Zanna

ここでの正しいツールは、@ Zannaによる 推奨 としてのjoinですが、これはawkアプローチです:

$ awk 'NR==FNR{a[$1]=$2; next}{print $1,a[$1]}' completed_tests.txt all_tests.txt 
test1 Passed
test2 
test3 Failed
test4 
test5 Passed
test6 Passed
7
terdon

Perl

事実上、これは苦痛の答えのポートです:

$ Perl -lane '$t+=1; $h{$F[0]}=$F[1] if $.==$t; print $F[0]," ",$h{$F[0]} if $t!=$.;$.=0 if eof' completed_tests.txt all_tests.txt          
test1 Passed
test2 
test3 Failed
test4 
test5 Passed
test6 Passed

これは、completed_test.txtからテストステータスペアのハッシュを構築し、そのハッシュでall_tests.txtの行を検索することにより機能します。各ファイルから処理された合計行の$t変数と、ファイルの終わりに達するとリセットされる$.により、現在読み取られているファイルを追跡できます。

2