使用jq循环遍历json以获取多个值

时间:2016-08-29 10:36:21

标签: arrays json bash 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",
    }
]
}

我需要将VolumeIdTags.Value的值都用作调用另一个命令的输入。从json数组中获取单个值很容易,但是我无法从中提取多个值并将其传递给另一个bash命令。

我可以使用这个获得单个值:

cat volumes.json |jq -r '.Volumes[].VolumeId' |while read v; do another_bash_command $v; done

但是我无法获得多个值,因为这是错误的:

 cat volumes.json |jq -r '.Volumes[].VolumeId, .Volumes[].Tags[].Value' |while read v w; do another_bash_command $v $w; done

因为它会循环6次结果而不是3次。

,如何将循环中的多个json值传递给bash数组,以便更好地使用该值?与VolumeId-> $arr[0][0]Tags.Value-> $arr[0][1]AvailabilityZone-> $arr[0][2]等相同。我搜索了SO和jq文档,并尝试了readarray,但仍然无法找到解决方案:(感谢您给予的任何帮助。

3 个答案:

答案 0 :(得分:5)

在我看来,您想在同一行输出两个值(VolumeIdTags[].Value)?

如果是这种情况,那么简单的字符串连接就足够了:

$ jq -r '.Volumes[] | .VolumeId + " " + .Tags[].Value' volumes.json
vol-00112233 vol-rescue-system
vol-00112234 vol-rescue-swap
vol-00112235 vol-rescue-storage

然后可以在具有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

您应该注意,如果Tags中有多个元素,结果将反映出来。但是,可以通过引用Tags中的第一个元素来避免这种情况:.Tags[0].Value

答案 1 :(得分:4)

正如@andlrc所观察到的,如果任何一个Tags数组有多于或少于一个元素,你可能需要决定你真正想要的是什么。假设您在所有情况下都需要Tags[0],我建议您考虑使用@tsv,如下所示:

jq -r '.Volumes[] | [.VolumeId, .Tags[0].Value] | @tsv' volumes.json

如果任何.VolumeId.Tags[0].Value值包含空格,制表符,换行符等,这将特别合适。重点是@tsv将以标准方式处理这些值,以便处理这对值也可以以标准方式完成。例如。使用awk,你可以在awk -F\\t对中阅读;使用bash,IFS=$'\t'

答案 2 :(得分:2)

我知道问题是关于如何使用jq获取信息,但也可以使用--query标志直接从aws cli获取预期参数。

aws ec2 describe-volumes --query "Volumes[].[VolumeId, Tags[].Value]" --output text