複数のファイル(10個以上)があり、それを1つの出力ファイルにマージ/結合したいと思います。たとえば、次のようになります。
ファイル1
2000 0.0202094
2001 0.0225532
2002 0.02553
2003 0.0261099
2004 0.0280311
2005 0.028843
ファイル2
2000 0.0343179
2001 0.036318
2003 0.039579
2004 0.0412106
2005 0.041264
ファイル3
2004 0.068689
2005 0.0645474
すべてのファイルには同じ2つの列がありますが、長さは異なります。
希望の出力は次のとおりです。
file1 file2 file3
2000 0.0202094 0.0343179
2001 0.0225532 0.036318
2002 0.02553
2003 0.0261099 0.0395799
2004 0.0280311 0.0412106 0.0686893
2005 0.028843 0.041264 0.0645474
次のコードを試しましたが、値が最初の列と一致しません。
awk '{printf($1); for(i=2;i<=NF;i+=2) printf ("\t%s", $i); printf "\n"}' <(paste file*) > mergedfile.txt
答え1
awk
最初の列項目をグループ化して、これらのファイルを一度に実行できます。この部分map[$1]?(map[$1] FS $2):($2)
は三項ステートメントです。つまり、空の場合はインデックス付き配列マップに追加し$1
、空でない場合は既に存在する値に追加するという意味です。
awk '{ map[$1] = ($1 in map)?(map[$1] FS $2):($2); }
END { for(i in map) print i, map[i] }' file*
生成された出力よりも出力を読みやすくするには、awk
出力を次のようにパイプします。
awk '{ map[$1] = ($1 in map)?(map[$1] FS $2):($2); }
END { for(i in map) print i, map[i] }' file* | column -t > mergedfile.txt
答え2
次のスクリプトで完了
STEP1
awk '{print $1}' file1 file2 file3| awk '{if(!seen[$1]++){print $0}}' >pattern_content
STEP2
for i in `awk '{print $1}' file1 file2 file3| sort | uniq`; do grep "$i" file1>/dev/null; if [[ $? == 0 ]]; then grep $i file1| awk '{print $2}'; else echo " "; fi; done > file1_o
for i in `awk '{print $1}' file1 file2 file3| sort | uniq`; do grep "$i" file2>/dev/null; if [[ $? == 0 ]]; then grep $i file2| awk '{print $2}'; else echo " "; fi; done > file2_o
for i in `awk '{print $1}' file1 file2 file3| sort | uniq`; do grep "$i" file3>/dev/null; if [[ $? == 0 ]]; then grep $i file3| awk '{print $2}'; else echo " "; fi; done > file3_o
step3
paste pattern_content file1_o file2_o file3_o|sed '1i file1 file2 file3'| sed "s/file1/\t&/g"
出力
file1 file2 file3
2000 0.0202094 0.0343179
2001 0.0225532 0.036318
2002 0.02553
2003 0.0261099 0.0395799
2004 0.0280311 0.0412106 0.0686893
2005 0.028843 0.041264 0.0645474