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

时间:2016-12-19 06:29:28

标签: bash jq

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

  1. 需要进行多个CURL调用(响应具有相同的结构但不同的值),应用一些逻辑/过滤器,然后整理一个最终JSON对象数组中的所有响应。
  2. 遍历此最终JSON数组并以预定义格式写入CSV。
  3. 搜索了两个要求,但找不到具体的东西。请指教。下面突出显示的步骤(***)是我需要帮助的地方。

    样本流程

    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
      }
    ]
    

3 个答案:

答案 0 :(得分:2)

for service in "$services" ; do curl "$service/path" done | jq -r '.[]|[.id,.startDate,.calls]|@csv' 可以处理多个输入数组。您可以将循环的整个输出传递给它:

@csv

请注意,csv转换可以通过{{1}}

完成

答案 1 :(得分:2)

正如@ hek2mlg指出的,应该可以只调用一次jq。如果输入足够统一(诚然,可能是一个很大的&#34;如果&#34;),你甚至可以避免明确地命名字段,例如:

$ 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可以对所有输入执行任意计算,例如数数。

答案 2 :(得分:1)

你不需要&#34;最终&#34;阵列。您可以处理每个curl调用的单个JSON输出,并使用相同的jq脚本解析每个JSON输出,将JSON输入转换为CSV输出。有点像:

for url; do
    curl "$url" | jq 'filter-and-extract-csv-columns'
done > output.csv

注意整个循环重定向到output.csv

由于CVS格式是平坦的,没有像XML或JSON那样的周围环境,因此可以实现这种简化的处理。多个计算的输出可以简单地连接起来。