シェルでループ時のデリミタを切り替えたい
2007年11月12日
ボーンシェルで、文字列をfor文に突っ込んでループするときの、分割文字の指定方法のことです。
本当は改行区切りの各文字列でループさせたいのに、文字列中の半角空白とかでも分割されてループしてしまう・・・と言う状況への対処です。
改行文字で”aaa bbb ccc” “AAA BBB CCC” “111 222 333″ の文字列でループさせたいのに、”aaa” “bbb” “ccc” … でループしてしまう例。
#!/bin/sh SUBJECT="aaa bbb ccc AAA BBB CCC 111 222 333" for i in $SUBJECT do echo "----" echo $i done
出力
---- aaa ---- bbb ---- ccc ---- AAA ---- BBB ---- CCC ---- 111 ---- 222 ---- 333
9回回ってしまいます。
なお、”$SUBJECT” という記述でfor文に入れると、逆に1回しかループしません。
対処法
#!/bin/sh ORG_IFS=$IFS MOD_IFS=" " SUBJECT="aaa bbb ccc AAA BBB CCC 111 222 333" IFS=$MOD_IFS for i in $SUBJECT do IFS=$ORG_IFS echo "----" echo $i IFS=$MOD_IFS done IFS=$ORG_IFS
出力
---- aaa bbb ccc ---- AAA BBB CCC ---- 111 222 333
OK-
ボーンシェルには$IFSという環境変数があって、これがfor文に渡す文字列のデリミタとして使用されます。
ので、それをfor文実行前に変えてやれば良いということです。
上記例で、ORG_IFSにこまめに戻しているのは、for文の中でまたfor文を使うとき用の対処です、必須じゃないっす。
ので、それをfor文実行前に変えてやれば良いということです。
上記例で、ORG_IFSにこまめに戻しているのは、for文の中でまたfor文を使うとき用の対処です、必須じゃないっす。
参考: http://www.tsden.org/takamiti/shText/shText030.html (“IFS”でページ内検索をしてください)