syl*_*lye 3 arrays bash json jq
这是volumes.json:
{
"Volumes": [
{
"AvailabilityZone": "us-east-1a",
"Tags": [
{
"Value": "vol-rescue-system",
"Key": "Name"
}
],
"VolumeId": "vol-00112233",
},
{
"AvailabilityZone": "us-east-1a",
"Tags": [
{
"Value": "vol-rescue-swap",
"Key": "Name"
}
],
"VolumeId": "vol-00112234",
},
{
"AvailabilityZone": "us-east-1a",
"Tags": [
{
"Value": "vol-rescue-storage",
"Key": "Name"
}
],
"VolumeId": "vol-00112235",
}
]
}
Run Code Online (Sandbox Code Playgroud)
我需要获取和的值,VolumeId并将Tags.Value其用作调用另一个命令的输入.从json数组中获取单个值很容易,但我无法从中提取多个值并将其传递给另一个bash命令.
我可以使用这个得到一个值:
cat volumes.json |jq -r '.Volumes[].VolumeId' |while read v; do another_bash_command $v; done
Run Code Online (Sandbox Code Playgroud)
但我无法获得多重值因为这是错误的:
cat volumes.json |jq -r '.Volumes[].VolumeId, .Volumes[].Tags[].Value' |while read v w; do another_bash_command $v $w; done
Run Code Online (Sandbox Code Playgroud)
因为它将循环6次结果而不是3次.
并且,如何将循环中的多个json值传递给bash数组,以便我可以更好地使用该值?像VolumeId-> $arr[0][0],Tags.Value-> $arr[0][1],AvailabilityZone-> $arr[0][2]...等等.我搜索了SO和jq文档,并尝试过readarray,但仍然无法找到解决方案:(感谢您给予的任何帮助.
在我看来,你想在同一行输出两个值(VolumeId和Tags[].Value)?
如果是这种情况,那么简单的字符串连接就足够了:
$ jq -r '.Volumes[] | .VolumeId + " " + .Tags[].Value' volumes.json
vol-00112233 vol-rescue-system
vol-00112234 vol-rescue-swap
vol-00112235 vol-rescue-storage
Run Code Online (Sandbox Code Playgroud)
以上内容可用于以下管道while-read:
$ cat my_script
jq -r '.Volumes[] | .VolumeId + " " + .Tags[].Value' volumes.json \
| while IFS= read -r volumeId tagValue; do
other_command "$volumeId" "$tagValue"
done
Run Code Online (Sandbox Code Playgroud)
您应该注意,如果结果中有多个元素Tags将反映出来.但是,可以通过引用第一个元素来避免这种情况Tags:.Tags[0].Value
正如@andlrc 所观察到的,如果任何标签数组的元素多于或少于一个,您可能需要决定您真正想要什么。假设您Tags[0]在所有情况下都想要,我建议您考虑使用 @tsv,如下所示:
jq -r '.Volumes[] | [.VolumeId, .Tags[0].Value] | @tsv' volumes.json
Run Code Online (Sandbox Code Playgroud)
如果任何.VolumeId或.Tags[0].Value值包含空格、制表符、换行符等,这将特别合适。关键是@tsv 将以标准方式处理这些,因此处理这对值也可以以标准方式完成. 例如,使用 awk,您可以使用awk -F\\t; 使用 bashIFS=$'\t'等