如何使用jq将数据从多个输入json对象复制到一个输出对象?

时间:2017-06-14 12:52:34

标签: json edit jq

我有一个文件,其中每一行都是json对象的数组,如:

[
  {
    "ts": "2017-06-13 16:59:35,778"
  },
  {
    "id": 39,
    "path": "/1497365920809-31368-6D8E756916AE1",
    "messageAttributes": {
      "some_obsolete_data": "1497365975532",
      "more_obsolete_data": "20",
      "c": ""
    }
  },
  {
    "id": 40,
    "path": "/1497365920809-31368-6D8E756916AE1",
    "messageAttributes": {
      "some_obsolete_data": "some text",
      "data_that_I_Need": "Name,1,Text,1497365975568"
    }
  }
]

每个数组的第一个对象将始终是我需要的“时间戳”,但以下对象可能会或可能不会引起关注。

现在我需要让jq将每一行转换为包含时间戳和data_that_I_Need的json对象数组,如

[
  {
    "ts": "2017-06-13 16:59:35,778",
    "id": 40,
    "path": "/1497365920809-31368-6D8E756916AE1",
    "messageAttributes": {
      "data_that_I_Need": "Name,1,Text,1497365975568"
    }
  }
]

通过

jq '
  .[]                                                 | 
  select(.messageAttributes.data_that_I_Need != null) |
  {
    id   : .id, 
    path : .path, 
    messageAttributes: { 
      dataThat_I_Need: .messageAttributes.data_that_I_Need
    }
  }
' <my_file.txt 

我可以过滤掉过时的数据。

但是如何将第一个对象中的“ts”字段添加为输出中的字段?

更新

看起来我可以在程序的开头设置一个变量,我可以用于所有后续对象......

jq '
  .[0].ts as $ts                                      |
  .[]                                                 |
  select(.messageAttributes.data_that_I_Need != null) |
  {
    ts   : $ts, 
    id   : .id, 
    path : .path, 
    messageAttributes: { 
      dataThat_I_Need: .messageAttributes.data_that_I_Need
    }
  }
' <my_file.txt

1 个答案:

答案 0 :(得分:2)

UPDATE中的答案非常好,但这里有一个变体,说明了几点,特别是不需要变量,{x}可以用作{x: .x}的缩写:

.[0] 
+ (.[]
   | select(.messageAttributes.data_that_I_Need != null)
   | {id, 
      path,
      messageAttributes: {dataThat_I_Need: .messageAttributes.data_that_I_Need}} )