bash jq - 创建空数组并向其中添加对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41216894/
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
jq - create empty array and add objects to it
提问by Vinay
I am working on a bash script (using jq for JSON parsing)
我正在编写一个 bash 脚本(使用 jq 进行 JSON 解析)
- that needs to make multiple CURL calls (response has same structure but different values), apply some logic/filters and then collate all the responses in one final JSON array of objects.
- Loop through this final JSON array and write into a CSV in a predefined format.
- 这需要进行多次 CURL 调用(响应具有相同的结构但不同的值),应用一些逻辑/过滤器,然后将所有响应整理到一个最终的 JSON 对象数组中。
- 循环遍历这个最终的 JSON 数组并以预定义的格式写入 CSV。
Searched for a bit for both the requirements but could not find anything concrete. Please advice. The highlighted steps below (in ***) are the points where I need help.
搜索了一下这两个要求,但找不到任何具体的东西。请指教。下面突出显示的步骤(在 *** 中)是我需要帮助的地方。
Sample Flow :
样品流程:
create empty FINAL array
for(eachService is serviceList)
a. CURL <service_response> returning JSON array of objects
b. use jq filters to parse JSON response, apply some logic and modify elements in response as needed
c. ***add this JSON array to FINAL array***
***LOOP through FINAL array, one object at a time a write to CSV.***
Sample Data :
样本数据 :
CURL Response 1 (ex: $curl1):
[
{
"id":"123",
"startDate": "2016-12-09T00:00:00Z",
"calls":4
},
{
"id":"456",
"startDate": "2016-12-09T00:00:00Z",
"calls":22
}
]
CURL Response 2 (ex : $curl2):
[
{
"id":"789",
"startDate": "2016-12-09T00:00:00Z",
"calls":8
},
{
"id":"147",
"startDate": "2016-12-09T00:00:00Z",
"calls":10
}
]
NEEDED OUTPUT ($final):
[
{
"id":"123",
"startDate": "2016-12-09T00:00:00Z",
"calls":4
},
{
"id":"456",
"startDate": "2016-12-09T00:00:00Z",
"calls":22
},
{
"id":"789",
"startDate": "2016-12-09T00:00:00Z",
"calls":8
},
{
"id":"147",
"startDate": "2016-12-09T00:00:00Z",
"calls":10
}
]
回答by hek2mgl
jq
can deal with multiple input arrays. You can pipe the whole output of the loop to it:
jq
可以处理多个输入数组。您可以将循环的整个输出通过管道传递给它:
for service in "$services" ; do
curl "$service/path"
done | jq -r '.[]|[.id,.startDate,.calls]|@csv'
Note that the csv transformation can be done by @csv
请注意,csv转换可以通过 @csv
回答by peak
As @hek2mlg pointed out, it should be possible to invoke jq just once. If the input is sufficiently uniform (admittedly, maybe a big "if"), you could even avoid having to name the fields explicitly, e.g.:
正如@hek2mlg 指出的那样,应该可以只调用一次 jq。如果输入足够统一(诚然,可能是一个很大的“if”),您甚至可以避免必须明确命名字段,例如:
$ for service in "$services" ; do
curl "$service/path"
done | jq -sr 'add[] | [.[]] | @csv'
Output:
输出:
"123","2016-12-09T00:00:00Z",4
"456","2016-12-09T00:00:00Z",22
"789","2016-12-09T00:00:00Z",8
"147","2016-12-09T00:00:00Z",10
Note that using -s allows you to perform arbitrary computations on all the inputs, e.g. counting them.
请注意,使用 -s 允许您对所有输入执行任意计算,例如对它们进行计数。
回答by janos
You don't need a "final" array. You can process the individual JSON output of each curl
call, and parse each with the same jq
script, converting JSON input to CSV output. Something along the lines of:
您不需要“最终”数组。您可以处理每个curl
调用的单独 JSON 输出,并使用相同的jq
脚本解析每个输出,将 JSON 输入转换为 CSV 输出。类似的东西:
for url; do
curl "$url" | jq 'filter-and-extract-csv-columns'
done > output.csv
Notice the redirection of the entire loop to output.csv
.
注意整个循环重定向到output.csv
.
This kind of streamlined processing is possible thanks to the CVS format being flat without a surrounding context as in XML or JSON. The output of multiple computations can be simply concatenated.
由于 CVS 格式是扁平的,没有像 XML 或 JSON 那样的周围上下文,因此这种简化的处理成为可能。多个计算的输出可以简单地连接起来。