jq - 创建空数组并向其中添加对象
jq - create empty array and add objects to it
我正在编写 bash 脚本(使用 jq 进行 JSON 解析)
- 需要进行多次 CURL 调用(响应具有相同的结构但值不同),应用一些 logic/filters,然后将所有响应整理到一个最终的 JSON 对象数组中。
- 遍历这个最终的 JSON 数组并以预定义格式写入 CSV。
对这两个要求进行了一些搜索,但找不到任何具体内容。请指教。下面突出显示的步骤(在 *** 中)是我需要帮助的地方。
示例流程:
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.***
示例数据:
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
}
]
您不需要 "final" 数组。您可以处理每个 curl
调用的单独 JSON 输出,并使用相同的 jq
脚本解析每个输出,将 JSON 输入转换为 CSV 输出。大致如下:
for url; do
curl "$url" | jq 'filter-and-extract-csv-columns'
done > output.csv
注意整个循环重定向到 output.csv
。
这种简化的处理是可能的,因为 CVS 格式是扁平的,没有像 XML 或 JSON 中那样的周围上下文。多个计算的输出可以简单地连接起来。
jq
可以处理多个输入数组。您可以将循环的整个输出通过管道传递给它:
for service in "$services" ; do
curl "$service/path"
done | jq -r '.[]|[.id,.startDate,.calls]|@csv'
注意csv转换可以通过@csv
完成
正如@hek2mlg 所指出的,应该可以只调用 jq 一次。如果输入足够统一(诚然,可能是一个大 "if"),您甚至可以避免显式命名字段,例如:
$ for service in "$services" ; do
curl "$service/path"
done | jq -sr 'add[] | [.[]] | @csv'
输出:
"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
请注意,使用 -s 允许您对所有输入执行任意计算,例如数数。
我正在编写 bash 脚本(使用 jq 进行 JSON 解析)
- 需要进行多次 CURL 调用(响应具有相同的结构但值不同),应用一些 logic/filters,然后将所有响应整理到一个最终的 JSON 对象数组中。
- 遍历这个最终的 JSON 数组并以预定义格式写入 CSV。
对这两个要求进行了一些搜索,但找不到任何具体内容。请指教。下面突出显示的步骤(在 *** 中)是我需要帮助的地方。
示例流程:
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.***
示例数据:
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
}
]
您不需要 "final" 数组。您可以处理每个 curl
调用的单独 JSON 输出,并使用相同的 jq
脚本解析每个输出,将 JSON 输入转换为 CSV 输出。大致如下:
for url; do
curl "$url" | jq 'filter-and-extract-csv-columns'
done > output.csv
注意整个循环重定向到 output.csv
。
这种简化的处理是可能的,因为 CVS 格式是扁平的,没有像 XML 或 JSON 中那样的周围上下文。多个计算的输出可以简单地连接起来。
jq
可以处理多个输入数组。您可以将循环的整个输出通过管道传递给它:
for service in "$services" ; do
curl "$service/path"
done | jq -r '.[]|[.id,.startDate,.calls]|@csv'
注意csv转换可以通过@csv
正如@hek2mlg 所指出的,应该可以只调用 jq 一次。如果输入足够统一(诚然,可能是一个大 "if"),您甚至可以避免显式命名字段,例如:
$ for service in "$services" ; do
curl "$service/path"
done | jq -sr 'add[] | [.[]] | @csv'
输出:
"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
请注意,使用 -s 允许您对所有输入执行任意计算,例如数数。