ソースコードから理解する技術-UnderSourceCode

手を動かす(プログラムを組む)ことで技術を理解するブログ

Shellで複数の結果をそのままforループさせる

普段はあまりシェルを書かないので手続き的に書こうとしてハマったのでメモ代わりに書いておきます。
タイトルにあるように、あるコマンドを実行して結果が複数返ってくるとします。
この結果をループして別処理を呼び出す引数にしようとしたら、思ったよりハマってしまいました。

結論としては、
1.あるコマンドを実行する
2.その1.の結果を配列などの変数に保持する
3.変数をループする

とするのではなく、

1.あるコマンドを実行する
2.それをそのままfor~inに渡す

とすれば良かったようです。
ソースを見た方が早いので以下にサンプルを上げます。

サンプル

以下のようなjsonをjqで解析して「name」の数だけループして値を別処理の引数とするとします。

sample.json

{
    "name": "name1",
    "description": "description1"
}
{
    "name": "name2",
    "description": "description2"
}
{
    "name": "name3",
    "description": "description3"
}

シェルは以下のようになりました。

sample.sh

#!/bin/sh

for value in $(cat sample.json | jq .name)
do
    echo "name = "$value
done

実行すると以下のように「name」の値を取得して別処理(今回はecho)に渡していることが分かります。

$ ./sample.sh
name = "name1"
name = "name2"
name = "name3"

まとめ

分かってしまえば簡単なのですが、jqの結果をそのままfor~inに渡すというのを直ぐに思いつきませんでした。
将来の自分や誰かの役に立てば幸いです。

追記

以下のように「declare -a」を使って最初に考えた結果を配列などの変数に保持する方法もできるようです。

sample2.sh

#!/bin/bash

declare -a ary=$(cat sample.json | jq .name)
for value in $ary
do
    echo $value
done