複数のtxtファイルをマージする

複数のtxtファイルをマージする

複数のtxtファイルがあり、そのうち3つは次のとおりです。

ファイル1:

sample  input filtered
5809378   1      2
5811151   3      4
5811237   5      6

ファイル2:

sample  chi tri
5809378  7   8
5811151      
5811237  9   10

ファイル3:

sample   bra  doe
5809378  11 
5811151        12
5811237  13    14

この3つのファイルを最初の列(サンプルID)に基づいて1つのファイルにマージしようとしているので、出力は次のようになります。

sample  input  filters  chi  tri   bra   doe
5809378    1     2      7     8     11     0
5811151    3     4      0     0     0     12
5811237    5     6      9     10    13    14

そのデータがない場合はゼロが必要で、最悪の場合は空のタブが必要です。

awkとJoinを試しましたが、最良の解決策が見つかりませんでした。誰でもどんなアイデアがありますか?

ベストアンサー1

私の観点から見ると、file3は次の行のため完全に正確ではありません。

5811151 12

ファイルの読み方によっては、2番目または3番目の列に数字「12」がある場合があります(列区切り文字は定義されておらず、どこでも異なります)。

それでも。

a=$(cat file1|awk '{if($2==""){$2="0"};if($3==""){$3="0"}; print $1,$2,$3}'|sort);
for f in file2 file3; do
    b=$(cat $f|awk '{if($2==""){$2="0"};if($3==""){$3="0"}; print $1,$2,$3}'|sort);
    a=$(join -j 1 <(echo "${a}") <(echo "${b}"));
done;
echo "${a}"|sort -n

出力は次のとおりです

sample input filtered chi tri bra doe
5809378 1 2 7 8 11 0
5811151 3 4 0 0 12 0
5811237 5 6 9 10 13 14

だから私たちは

1)キャプチャされたすべてのファイルが変換されます。

cat file|awk '{if($2==""){$2="0"};if($3==""){$3="0"}; print $1,$2,$3}'|sort

欠落している数字を「0」に置き換えて行を並べ替えます。

2) ループから次のファイルをインポートし、前の結果にマージします。

join -j 1 file_current file_next

したがって、「for f in file2 file3; do」行は、「for f in file2 file3 file4 file5 file6; do」など、より多くのファイルを含むように変更できます。

3)結果を印刷し、文字列の値に基づいてソートします。(最初に列名をソートして印刷します。)必要に応じて、ここで出力形式を指定することもできます。

おすすめ記事