[Linux] Bashでlsやfindの実行結果を1件ずつ処理したい

Bashでlsなどコマンドの実行結果を順番に処理したい場合は以下のようにforでぐるぐる回してやるだけです。

#!/bin/bash

for file in `ls /tmp/*.json`; do
  echo "copy ${file} to /home/foo"
  cp $file /home/foo
done

ここでは「/tmp」ディレクトリ配下にある拡張子が.jsonのファイルを順番に指定ディレクトリへコピーしています。対象のファイルが存在しない場合は何もしません。

find版

もちろんlsの箇所をfindなど他のコマンドに置き換えても同様に動作します。

#!/bin/bash

for file in `find /tmp -name '*.json'`; do
  echo "copy ${file} to /home/foo"
  cp $file /home/foo
done

ファイルを探し出すことにかけてfindは変態的なまでにオプションが充実しているので、lsでは荷が重くなってきたらfindにバトンタッチしてやるのが良いでしょう。

特定のファイルを対象にする

lsやfindは事前にファイル名がわからないような場合や、対象が大量にある場合に非常に役立ちますが、対象のファイルが2〜3個でなおかつ事前に判明しているような場合は、決め打ちで処理します。 blog.katsubemakito.net

おまけ

エラー処理

実際に利用する場合はコマンドの実行結果も確認した方が良いですね。

#!/bin/bash

for file in `ls /tmp/*.json`; do
  echo "copy ${file} -> /home/foo"
  cp $file /home/foo

  # コピー出来なければ終了
  if [ $? -ne 0 ]; then
    echo "[Error] Can not copy file (${file})"
    exit 1;
  fi
done

実行結果は変数$?へ自動的に代入されます。Linuxではほとんどのコマンドは戻り値が0であれば正常、それ以外は何らかのエラーが発生していることを指します。

すべてのコマンドは終了時にステータス値を返す。 この値を検査することで (例えば、ほとんどのシェルでは変数 $? に最後に実行したコマンドのステータスが保持される)、 そのコマンドが成功して完了したかどうかを知ることができる。 伝統的に、終了ステータス 0 は成功を示すのに使われ、非 0 の値は そのコマンドが成功しなかったことを示す (終了ステータスの詳細は wait(2) に書かれている)。 非 0 の終了ステータスは 1 から 255 の範囲の値をとることができ、 いくつかのコマンドではコマンドが失敗した理由を示すために 複数の非 0 のステータス値が使用されている。

Linux User's Manual (1)より

参考ページ