実践bashの使い方 バッククォートでforループ

投稿日:

実際に業務で直面したお話です。誰かがどこかで参考にしてくれるかもしれないのでメモを残しておきます。

■問題
$HOME/tmp/target の中にある18,000個のテキストファイルの内容を1個のテキストファイル $HOME/tmp/a.txt にまとめよ

テキストファイルの内容は
・全て1行のplain text
・末尾に改行コードは入っていない
・データの文字コードはShift_JIS

出力する1個のファイルに
・改行区切り、18,000行のファイルにまとめたい
・順番はどーでもいい
・文字コードはオリジナル(Shift_JIS)のまま

Macならterminal.appで、Linuxならgnome-termialでおながいします。

■回答例

for i in `ls $HOME/tmp/target`; do (cat $i; echo;) >> $HOME/tmp/a.txt; done

shで「`(半角バッククォート)」を使うとバッククォートで囲まれたコマンド実行結果をコマンドに渡せるです。
なので上記だと

ls $HOME/tmp/target

の実行結果、つまり18,000個のテキストファイルのリストが取れる、と。

それを

for i in

でbashのforループに喰わせてやってます。18,000回ループするんですね。

18,000回ループさせる処理の内容が「((半角括弧)」で囲ってあって、catコマンドとechoコマンドを使ってます。catはそのままファイルの中身を出力するだけ。echoしているのは今回の問題のファイルは終端に改行コードが入っていなかったので、そのままcatするだけだとa.txtには改行コードが入らない。のでechoで改行コードをぶち込んでやる。

a.txtへの書き込みは>>でリダイレクトしているだけ。

最後に
wc -l $HOME/tmp/a.txt
として結果が18,000であることを確認すれば完璧。なはず。


難しく考えてperlとかPHPを使い出すと30分くらいハマれるよw


# ツッコミや「もっと手っ取り早い方法あるよ!」大歓迎!!!