【问题标题】:Loop through json using jq to get multiple value使用jq循环json获取多个值
【发布时间】:2017-01-05 08:40:14
【问题描述】:

这里是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 数组中获取单个值很容易,但我无法从中提取 multiple value 并将其传递给另一个 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,但仍然无法找到解决方案:(感谢您提供的任何帮助。

【问题讨论】:

    标签: arrays json bash jq


    【解决方案1】:

    在我看来,您想在同一行输出两个值(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

    【讨论】:

      【解决方案2】:

      正如@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' 等。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • jamespath (由 --query 使用)为此太棒了,可惜有些事情你不能用它做而你可以用 jq 做(参见例如news.ycombinator.com/item?id=16400320,justin_oaks 于 2 月发表评论2018 年 1 月 17 日)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-07
        • 1970-01-01
        相关资源
        最近更新 更多