bash の for ループは for ..in スタイル
bash では、for ループを for .. in スタイルで記述することが一般的です。 もちろん、C言語スタイルのbash のfor ループを記述することも可能です→参考
一般的に使われるのは for ... in
スタイルではないでしょうか。言語によっては for each / foreach / イテレーション
などとも呼ばれます。
for .. in スタイルの例
$ for name in takuya yuki koji ; do echo $name.txt ; done takuya.txt yuki.txt koji.txt
for in で記述する場合は、for の要素をスペース区切り直接文字列で記述することが出来ます。
コマンド結果と組み合わせる
for in ループは、そのまま単体で使うことは少ないです。コマンドの結果と組み合わせて使うほうがおなじみでしょう。
$( コマンド )
の結果を for in ループで回すことで柔軟な記述が可能になります。
$ for name in $( ls /Users/takuya ) ; do echo $name ; done Applications Desktop Documents Downloads Library Music Pictures Sites
ただ、for ループは記述が煩雑になるのと並列実効性能に乏しいので、実際には xargs を使うことが多いです。
空白 区切り文字を変更する
for ループは空白文字すべてで区切るため、コマンドの実行結果に空白文字が含まれると少々めんどくさい事になります
# 空白文字が含まれる例
#次のようなディレクトリがあるとき takuya@Desktop$ ls /Applications/ | /usr/bin/grep -i Google Google Chrome.app Google Drive.app Google Photos Backup.app Google SketchUp 8 GoogleJapaneseInput.localized ## めんどうなことに・・・ takuya@Desktop$ for i in $( ls /Applications/ | /usr/bin/grep -i Google ) ; do echo $i ;done Google Chrome.app Google Drive.app Google Photos Backup.app Google SketchUp 8 GoogleJapaneseInput.localized
区切文字は環境変数IFSで決める
環境変数 IFS を指定すると、区切り文字を任意の文字列にすることが出来ます。
IFS 指定の例
takuya@Desktop$ IFS=$'\n' takuya@Desktop$ for i in $( ls /Applications/ | /usr/bin/grep -i Google ) ; do echo $i ;done Google Chrome.app Google Drive.app Google Photos Backup.app Google SketchUp 8 GoogleJapaneseInput.localized
空白を含む結果も無事に1行ごとに処理することが出来ます。
IFS=$'\n'について
IFSの指定で、改行を指定するのは次のように行います。
IFS=' '
ただし、これではあまりにわかりにくいです。また、bash履歴・ヒストリにもうまく残りません。
そこで、$
を使ってエスケープシーケンスを解釈させています。
IFS=$'\n'
for in と ブレース展開の組み合わせ。
for in ループは、bash のブレース展開と組み合わせて使うと便利に使うことが出来ます。
# for ..in ブレース展開の例
for idx in {00...5}; do echo $idx.jpg ; done
此のコマンドは次のような結果を得ます。
000.jpg 001.jpg 002.jpg 003.jpg 004.jpg 005.jpg
for と組み合わせてさらにコマンドを実行するときに便利です。 単に文字列を作成するだけなら、 ブレース展開だけで済んでしまう場面が多いことでしょう。
xargs の活用
しかし、わたしは、for ループより、じっさいには xargs を使うことが多いです。
for で記述するよりも xargs のほうがあとで再利用可能な履歴が残りやすく、再利用性を考慮するとxargs の方がいいことが多いです。
xargs には、並列実行のパラレル機能があり、コマンドの終了を待たずに次の処理を開始できることがあるためです。→ 並列実行はxargsコマンドのマルチプロセスを使うと楽ちん高速化ですね。 - それマグで!