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
Loop through json using jq to get multiple value
提问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 VolumeId
and Tags.Value
to 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 (VolumeId
and Tags[].Value
) on the same line?
在我看来,您想在同一行上输出两个值 (VolumeId
和Tags[].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 Tags
the 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 .VolumeId
or .Tags[0].Value
values 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 jq
but its also possible to directly get the expected parameter directly from aws cli using the --query
flag.
我知道问题是关于如何使用信息获取信息,jq
但也可以使用--query
标志直接从 aws cli 直接获取预期参数。
aws ec2 describe-volumes --query "Volumes[].[VolumeId, Tags[].Value]" --output text