更新(开始):回答以下几行,您就已经回答了完整的问题:
为什么会出现以下情况:
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]
注意:这是循环中的其中一行:
{"ipv4":["192.168.64.193"],"name":"node2","release":"20.04 LTS","state":"Running"}
答案1
不带引号的字符串.ipv4[]
是 shell 通配模式。此模式与任何现有文件都不匹配,并且您正在使用的 shell 配置为生成错误(如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
您不太可能需要将这些值放入数组中。相反,请一一阅读它们,然后对它们执行您需要执行的操作:
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
。