名前にスペースを含むファイル群をまとめて処理する

例えば

$ touch "1 hoge" "2 fuga" "3 piyo"
$ ls -1
1 hoge
2 fuga
3 piyo

のようにスペースを含むファイル名のものが多数ある場合に、「すべてのファイルに対してスペースをアンダースコアに置換したファイル名に変更したい!」というとき。
一気にやるためにはfor文を使いたい。ので、試しにこういうことをしてみる。

$ for FILE in `ls`; do echo $FILE; done

lsコマンドで出力されたファイル名をfor文の中でFILEという変数に格納し、毎回echo表示させる。
このechoの部分をmvとかにすればすべてのファイルに対し処理できそう。と思ったら…

$ for FILE in `ls`; do echo $FILE; done
1
hoge
2
fuga
3
piyo

結果はこの通り。for文で処理されるリストはスペースで区切られてしまうので、ファイル名が分解されてしまう。これではスペースを置換するどころの話じゃなくなる。
で、どうすれば良いかというと、もっとシンプルな方法でできるようだ。

$ for FILE in *; do echo $FILE; done
1 hoge
2 fuga
3 piyo

なんと、`ls`とかじゃなくて"*"を使ったワイルドカード指定を使うとうまく処理してもらえるらしい。
というわけで、スペースをアンダースコアに置換する場合は以下のようにする。

$ for FILE in *; do mv "$FILE" ${FILE/ /_}; done
$ ls -1
1_hoge
2_fuga
3_piyo

できあがり!!
ちなみにファイル名のスペースが2個以上ある場合は

$ for FILE in *; do mv "$FILE" ${FILE// /_}; done

と書く。
参考:
ファイル名の一括変更 - すぎゃーんメモ
http://matsui.homeunix.com/index.php?Bash%A5%B7%A5%A7%A5%EB%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8%2F%C6%C3%BC%EC%A4%CA%CA%D1%BF%F4%C5%B8%B3%AB

応用例

というか、何故これをやろうと思ったかというと。
Windowsで日本語のファイル名の物をLinuxFTP転送したら文字化けてしまったので、UTF-8に変更する方法を模索していたのです。

$ for a in *; do mv "$a" "$(echo $a | nkf -S -w)"; done

で一発解決でした。nkfってコマンド初めて知ったけど便利だわー。
Linuxコマンド集 - 【 nkf 】 文字コードを変換する:ITpro