更新(開始):次の行に答えると、質問全体に答えます。
なぜ次のような状況が発生しますか?
echo '{"ipv4":["192.168.64.193"]}'|jq .ipv4[0]
このエラーが発生します。
no matches found: .ipv4[0]
アップデート(完了)
このjsonで "ipv4"値を含むリスト変数を作成しようとしています。
{
"list": [
{
"ipv4": [
"192.168.64.193"
],
"name": "node2",
"release": "20.04 LTS",
"state": "Running"
},
{
"ipv4": [
"192.168.64.192"
],
"name": "node1",
"release": "20.04 LTS",
"state": "Running"
}
]
}
HOSTSはIPアドレスのリストです。
更新:@Kusalanandaのおかげで、スクリプトにこれを使用しました。HOSTS+=$(echo $i|jq '.ipv4[0]')
get_hosts(){
unset HOSTS
# unset NAMES
jq -c '.list[]' file.json | while read i; do
HOSTS+=$(echo $i | jq .ipv4)
# NAMES+=$(echo $i | jq .name)
done
echo $HOSTS
# echo $HOSTS
}
私は得る:
[
"192.168.64.193"
][
"192.168.64.192"
]
しかし、私は以下が必要です:
"192.168.64.193"
"192.168.64.192"
だから私は次のことを試みます:
...
HOSTS+=$(echo $i | jq .ipv4[0])
...
しかし、私は次のような結果を得ます:
get_hosts:3: no matches found: .ipv4[0]
get_hosts:3: no matches found: .ipv4[0]
注:以下はループの行の1つです。
{"ipv4":["192.168.64.193"],"name":"node2","release":"20.04 LTS","state":"Running"}
答え1
引用符のない文字列は.ipv4[]
シェルワイルドカードパターンです。このパターンは既存のファイルと一致せず、使用中のシェルはパターンをzsh
拡張せずに置くのではなく(デフォルトで)エラーを生成するように設定されています(bash
デフォルトでは)。
引用符で使用される表現jq
:
echo '{"ipv4":["192.168.64.193"]}' | jq '.ipv4[0]'
質問に提供したデータからすべてのIPアドレスを抽出するには、ipv4
すべての配列配列のすべての要素を取得しますlist
。
$ jq -r '.list[].ipv4[]' file
192.168.64.193
192.168.64.192
これらの値を配列に入れる必要はほとんどありません。代わりに、1つずつ読み、必要な操作を実行してください。
jq -r '.list[].ipv4[]' file |
while IFS= read -r ipaddr; do
# use "$ipaddr" here
done
各名前の名前と最初のIPアドレスを読み取るには、次の手順を実行します。
jq -r '.list[] | [ .name, .ipv4[0] ] | @tsv' file |
while IFS=$'\t' read -r name ipaddr; do
# use "$name" and "$ipaddr" here
done
この@tsv
演算子は、タブで区切られた配列出力を生成します。ここでは、配列の各エントリ名を対応するIPアドレスとペアに関連付けるために使用しますlist
。