読者です 読者をやめる 読者になる 読者になる

生物物理計算化学者の雛

主に科学に関する諸々を書き留めています。

複数ファイルの列データを1ファイルにまとめる

下記のように複数のファイル(ファイル名はd1.txt, d2.txt, d3.txtとする)に列データが分散している状態から、単一ファイルにまとめるシェルコマンド・スクリプトを紹介します。

cat d*.txt
==> d1.txt <==
      1.00 11.575308
      2.00 11.388116
      3.00 11.786263
      4.00 11.366100
      5.00 10.128717

==> d2.txt <==
      1.00 5.515582
      2.00 6.163193
      3.00 5.670080
      4.00 5.459511
      5.00 5.051750

==> d3.txt <==
      1.00 5.181342
      2.00 5.356774
      3.00 5.066935
      4.00 5.874455
      5.00 5.629000

単純に全ての列を統合したければ、pasteコマンド一発で統合できます。この場合ファイル名のアルファベット順に(つまりd1.txt, d2.txt, d3.txtの順)列が統合されます。

paste d*.txt 
      1.00 11.575308          1.00 5.515582           1.00 5.181342
      2.00 11.388116          2.00 6.163193           2.00 5.356774
      3.00 11.786263          3.00 5.670080           3.00 5.066935
      4.00 11.366100          4.00 5.459511           4.00 5.874455
      5.00 10.128717          5.00 5.051750           5.00 5.629000

次は全てのファイルで共通となっている1列目を最初の列として残して統合する方法です。2ファイルであればjoinコマンドで可能です。

join d1.txt d2.txt 
1.00 11.575308 5.515582
2.00 11.388116 6.163193
3.00 11.786263 5.670080
4.00 11.366100 5.459511
5.00 10.128717 5.051750

3ファイル以上ある場合は awk '{print $n}' によるn列目をとり出すコマンドを使ったシェルスクリプトで可能です。

awk '{print $1}' ./d1.txt > d0.column  # 共通である1列目をd0.columnとして抽出
                                       #(この出力ファイル名はアルファベット順で先頭になるように注意)
for f in d*.txt; do                    # 全ての d*.txt ファイルについて繰り返し
 awk '{print $2}' $f > $f.column       # 2列目データを取り出して、*.columnファイルに保存
done
paste *.column > output.txt            # *.column 全ての列を統合
rm *.column                            # 一時ファイルを削除

# 以下output.txtへの出力
1.00    11.575308       5.515582        5.181342
2.00    11.388116       6.163193        5.356774
3.00    11.786263       5.670080        5.066935
4.00    11.366100       5.459511        5.874455
5.00    10.128717       5.051750        5.629000

最後にテキストデータを扱うコマンドのわかりやすい説明がされている記事を紹介しておきます。
http://d.hatena.ne.jp/mi_kattun/20100916/1284631280