素晴らしいサイトを見つけた。年始から幸先良い。
困っていたのはこれ。
bashの区切り文字(IFS)は標準では「スペース(空白)とタブと改行」になってしまっているので、例えばfor文で複数ファイルに一括処理を回すときに空白を含むファイル名をうまく扱えない。
例えばこんなmp3があったとする。
ファイル名に大量に 半角スペース を含んでいる。
これを for文 に食わせてみるとこうなっちゃう。
$ for i in $(ls -rt | grep mp3 | tail -n 3); do echo "$i"; done
3曲だけ取り出せるはずが、1曲が(スペースでぶった切られて)バラバラになってしまっている。
これはファイル名の区切り文字(IFS)を「スペースとタブと改行」じゃなくて「改行だけ」に変更すればいいわけだが、たとえばこのサイトみたいに、OLDIFSに退避してあとから戻すようなのはダルい。
あくまで一時的にIFSを変更したいだけ。
これを実現するやり方が冒頭サイトにあった。サブシェルを使えば一時的にIFSを変更できるらしい。どの世界にもプロがいるものだ。
やってみる。
まず、現在のIFSを確認するにはこのコマンドを使う。
$ echo -n "$IFS" | od -b
サブシェルを使ってIFSを変更してみる。
$ echo -n "$IFS" | od -b
$ ( IFS=$'\n'; echo -n "$IFS" | od -b )
$ echo -n "$IFS" | od -b
なんてこった。素晴らしい。一時的なIFSの変更がワンライナーでできた。
さっきのmp3に適用してみる。
$ ( IFS=$'\n'; for i in $(ls -rt | grep mp3 | tail -n 3); do echo "$i"; done; )
グッハ素晴らしい。できた。最高。
前後のIFSの動きも見てみよう。
$ echo -n "$IFS" | od -b
$ ( IFS=$'\n'; for i in $(ls -rt | grep mp3 | tail -n 3); do echo "$i"; done; )
$ echo -n "$IFS" | od -b
これは良い。かなり重宝しそう。
IFSをデフォルトの「スペースとタブと改行」に戻すには
IFS="$'\n'$'\t' "
Windowsの場合