パイプで while read につなぐ方法
外部コマンドの出力結果を 1 行ずつ変数に取得しながらループ処理するには、コマンドの出力をパイプ (|
) で while read
につなぎます。
次の例では、外部コマンド find . -name '*.sh'
(カレントディレクトリ以下の .sh
ファイルを再帰的に列挙)の出力結果を 1 行ずつ line
変数に取得してループ処理しています。
find . -name '*.sh' | while read line; do
echo "$line"
done
line
という変数名は別の名前に変えても大丈夫です。
この例では 1 ファイルずつループ処理しているので、file
という変数名の方が直感的かもしれません。
☝️ ワンポイント
echo
出力時に "$line"
のようにダブルクォートで囲んでいるのは、echo
が連続したスペースを 1 つのスペースにまとめて出力してしまうのを防ぐためです。
パス内にスペースが含まれていなければ問題は発生しませんが、必ずダブルクォートで囲むようにしましょう。外部コマンドの出力を配列として受け取る方法
パイプ (|
) を使用せず、$(command)
の形で実行した外部コマンドの出力を、配列で受け取る方法もあります。
list=$(find . -name '*.sh')
for line in "$list"; do
echo "$line"
done
外部コマンドの出力を 1 行ずつ正しくループ処理するために、$list
をダブルクォートで囲むことを忘れないでください。
for
ループの in
の後ろには、スペース区切りで各要素が列挙されているものとして認識されます。
行内にスペースが含まれている場合に、行全体を 1 つの要素として処理するためには、$list
変数を展開するときにダブルクォートで囲んでおく必要があります。