それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

空白を含むファイル名や出力結果を1行ずつbash/forで扱うには。IFS シェルスクリプトの小手先

空白を含むファイル名を扱いたい。

最近のbash 最新版ならナニも考えずに、ファイル名の空白気にせず動くんですよ。

takuya@~/Desktop/tmp$ for i in * ; do echo $i; done ;
サンプル-01 [2016-04-05].txt
サンプル-02 [2016-04-05].txt
サンプル-03 [2016-04-05].txt

ファイル名であれば、ワイルドカードで済むとき「も」あります。

しかしコレがコマンドの結果を使うときなどに困ります。

たとえば、特定の拡張子のファイルを日付順に処理したいなど。

崩れる時があります。

気になるのは、シェル呼び出しをした結果をした場合

takuya@~/Desktop/tmp$ for i in $(ls *.txt) ; do echo $i; done ;
サンプル-01
[2016-04-05].txt
サンプル-02
[2016-04-05].txt
サンプル-03
[2016-04-05].txt

ああああああああああ、あるある!。これよくありますよね。マジ困る。

空白ファイル名作るな!とか絶叫したりしますよね。

IFS 変数を指定すると確実に解消する。

IFSとは Internal Field Separatorの略ですね。つまり、 cut コマンドの delimiter デリミタ(区切り文字)みたいなもんです。

IFSを設定することで、区切り文字を改行に限定できます。通常は空白文字全てですからね。

使い方

コマンドの実行前に、変数を宣言するだけ!

takuya@~/Desktop/tmp$ IFS=$'\n'

実行結果

IFSを実行前に設定するだけで、出力結果が、空白で区切られなくなって便利!!

takuya@~/Desktop/tmp$ IFS=$'\n'
takuya@~/Desktop/tmp$ for i in $(ls *.txt -v ) ; do echo $i; done ;
サンプル-01 [2016-04-05].txt
サンプル-02 [2016-04-05].txt
サンプル-03 [2016-04-05].txt

日付順に処理したって大丈夫。

ls の結果をそのまま1行ずつ処理できます。

takuya@~/Desktop/tmp$ IFS=$'\n'
takuya@~/Desktop/tmp$ for i in $(ls *.txt  -alt ) ; do echo $i; done ;
-rw-r--r-- 1 takuya staff 0  4  5 02:49 サンプル-03 [2016-04-05].txt
-rw-r--r-- 1 takuya staff 0  4  5 02:49 サンプル-02 [2016-04-05].txt
-rw-r--r-- 1 takuya staff 0  4  5 02:49 サンプル-01 [2016-04-05].txt

お手軽で楽チン!また詰まらないシェル芸を覚えてしまった。

参考資料

逆引きシェルスクリプト/スペースが含まれる文字列を1行として扱う方法 - Linuxと過ごす