🕌

bash で json を jq でスマートにループする

2022/09/07に公開1

例えば、こんな json があったときに、array 内のデータを取得して、ここに処理したい場合。

test.json
{
  "text": "test json",
  "array": [
    {
      "host": "mizuho",
      "ip": "192.168.0.10"
    },
    {
      "host": "mahoko",
      "ip": "192.168.0.11"
    },
    {
      "host": "tina",
      "ip": "192.168.0.21"
    }
  ]
}

length とか使って配列数分をループするなんてやり方してたんだけど、そんなこと必要なかった。ふつーに配列の対象(今回なら array) を、そのまま while read に食わせればよかったんだ。

test.sh
cat test.json |
jq -c '.array[]' |
while read -r array; do
  host=$(echo "${array}" | jq -r '.host')
  ip=$(echo "${array}" | jq -r '.ip')
  echo ${ip}${host} です
done

結果

192.168.0.10 は mizuho です
192.168.0.11 は mahoko です
192.168.0.21 は tina です

なんだそのホスト名は、という点は気にしないことが成功への近道

#今日のリファクタリング

Discussion

ko1nksmko1nksm

効率を考えればこちらの方が良いと思います。ループ毎に毎回 jq コマンドを呼び出す必要がないので。jq 力が弱いのでもっと良い書き方があるかもしれません。

jq -r '.array[] | [.host, .ip] | @tsv' test.json | (
  IFS=$(printf "\t") 
  while read -r host ip; do
    echo "$ip$host です"
  done
)