jq - 创建空数组并向其中添加对象

jq - create empty array and add objects to it

我正在编写 bash 脚本(使用 jq 进行 JSON 解析)

  1. 需要进行多次 CURL 调用(响应具有相同的结构但值不同),应用一些 logic/filters,然后将所有响应整理到一个最终的 JSON 对象数组中。
  2. 遍历这个最终的 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 允许您对所有输入执行任意计算,例如数数。