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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39204158/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 15:06:10  来源:igfitidea点击:

Loop through json using jq to get multiple value

arraysjsonbashjq

提问by sylye

Here is volumes.json :

这是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",
    }
]
}

I need to get both the value of VolumeIdand Tags.Valueto be used as the input to invoke another command. It is easy to get a single value from the json array, but I am not able to extract multiple valuefrom it and pass it to another bash command.

我需要得到双方的价值VolumeId,并Tags.Value用作输入来调用另一个命令。从 json 数组中获取单个值很容易,但我无法从中提取多个值并将其传递给另一个 bash 命令。

I can get a single value using this:

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

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

but I am not able to get multiple value cause this is wrong:

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

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

as it will then loop 6 times of the outcome instead of 3.

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

And, how do I pass those multiple json value in the loop to a bash array so I can use the value in a better way ? Like VolumeId-> $arr[0][0], Tags.Value-> $arr[0][1], AvailabilityZone-> $arr[0][2]...etc. I have searched through SO and the jq docs, and tried readarray, but still not able to find out the solution :( Thanks for any help given.

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

回答by andlrc

It seems to me that you want to output the two values (VolumeIdand Tags[].Value) on the same line?

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

If that's the case, then a simple string concatenation should be enough:

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

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

The above can then be used in a pipeline with while-read:

然后可以在管道中使用上述内容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

You should note that if there is more than one element in Tagsthe result will reflect that. This can however be avoided by referring the first element in Tags: .Tags[0].Value

您应该注意,如果结果中有多个元素Tags会反映出来。然而,这可以通过引用中的第一个元素来避免Tags.Tags[0].Value

回答by peak

As @andlrc observed, you may need to decide what you really want in the event that any Tags array has more or less than one element. Assuming you want Tags[0]in all cases, I would recommend considering the use of @tsv as follows:

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

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

This would be especially appropriate if any of the .VolumeIdor .Tags[0].Valuevalues contained spaces, tabs, newlines, etc. The point is that @tsv will handle these in a standard way, so that handling the pair of values can be done in a standard way as well. E.g. using awk, you could read in the pair with awk -F\\t; using bash, IFS=$'\t', etc.

如果.VolumeId.Tags[0].Value值中的任何一个包含空格、制表符、换行符等,这将特别合适。关键是@tsv 将以标准方式处理这些,因此也可以以标准方式处理这对值. 例如,使用 awk,您可以使用awk -F\\t; 使用 bashIFS=$'\t'

回答by Frederic Henri

I know the question is about how to get the information using jqbut its also possible to directly get the expected parameter directly from aws cli using the --queryflag.

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

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