将JSON数组拆分为单独的文件/对象

时间:2018-02-14 15:35:16

标签: json posix jq multiple-files

我以这种格式从Cassandra导出JSON。

[
  {
    "correlationId": "2232845a8556cd3219e46ab8",
    "leg": 0,
    "tag": "received",
    "offset": 263128,
    "len": 30,
    "prev": {
      "page": {
        "file": 0,
        "page": 0
      },
      "record": 0
    },
    "data": "HEAD /healthcheck HTTP/1.1\r\n\r\n"
  },
  {
    "correlationId": "2232845a8556cd3219e46ab8",
    "leg": 0,
    "tag": "sent",
    "offset": 262971,
    "len": 157,
    "prev": {
      "page": {
        "file": 10330,
        "page": 6
      },
      "record": 1271
    },
    "data": "HTTP/1.1 200 OK\r\nDate: Wed, 14 Feb 2018 12:57:06 GMT\r\nServer: \r\nConnection: close\r\nX-CorrelationID: Id-2232845a8556cd3219e46ab8 0\r\nContent-Type: text/xml\r\n\r\n"
  }]

我想将其拆分为单独的文件:

  

{           “correlationId”:“2232845a8556cd3219e46ab8”,           “腿”:0,           “tag”:“收到”,           “抵消”:263128,           “len”:30,           “prev”:{             “page”:{               “文件”:0,               “page”:0             },             “记录”:0           },           “data”:“HEAD / healthcheck HTTP / 1.1 \ r \ n \ r \ n”         }

  

{           “correlationId”:“2232845a8556cd3219e46ab8”,           “腿”:0,           “tag”:“已发送”,           “抵消”:262971,           “len”:157,           “prev”:{             “page”:{               “档案”:10330,               “页面”:6             },             “记录”:1271           },           “data”:“HTTP / 1.1 200 OK \ r \ n日期:2018年2月14日星期三12:57:06 GMT \ r \ n \ n服务器:\ r   Id-2232845a8556cd3219e46ab8 0 \ r \ n内容类型:text / xml \ r \ n \ r \ n“         }

我想使用jq,但没有找到方法。

请告知方法,如何通过文件分隔符将其拆分?

谢谢,雷迪

5 个答案:

答案 0 :(得分:2)

如果你有一个包含2个对象的数组:

jq '.[0]' input.json > doc1.json && jq '.[1]' input.json > doc2.json

结果:

$ head -n100 doc[12].json
==> doc1.json <==
{
  "correlationId": "2232845a8556cd3219e46ab8",
  "leg": 0,
  "tag": "received",
  "offset": 263128,
  "len": 30,
  "prev": {
    "page": {
      "file": 0,
      "page": 0
    },
    "record": 0
  },
  "data": "HEAD /healthcheck HTTP/1.1\r\n\r\n"
}

==> doc2.json <==
{
  "correlationId": "2232845a8556cd3219e46ab8",
  "leg": 0,
  "tag": "sent",
  "offset": 262971,
  "len": 157,
  "prev": {
    "page": {
      "file": 10330,
      "page": 6
    },
    "record": 1271
  },
  "data": "HTTP/1.1 200 OK\r\nDate: Wed, 14 Feb 2018 12:57:06 GMT\r\nServer: \r\nConnection: close\r\nX-CorrelationID: Id-2232845a8556cd3219e46ab8 0\r\nContent-Type: text/xml\r\n\r\n"
}

答案 1 :(得分:2)

您可以使用Python更有效地执行此操作(因为您可以读取整个输入一次,而不是每个文档读取一次):

import json

docs = json.load(open('in.json'))

for ii, doc in enumerate(docs):
    with open('doc{}.json'.format(ii), 'w') as out:
        json.dump(doc, out, indent=2)

答案 2 :(得分:2)

要将具有许多记录的json拆分为所需大小的块,我只需使用:

jq -c '.[0:1000]' mybig.json

类似于python切片。

在此处查看文档:{​​{3}}

  

数组/字符串切片:。[10:15]

     

。[10:15]语法可用于返回   数组的子数组或字符串的子字符串。传回的阵列   。[10:15]的长度为5,包含索引10中的元素   (含)到索引15(不含)。任一索引可能为负(以   在这种情况下,它从数组的末尾开始倒数),或者省略   (在这种情况下,它是指数组的开始或结尾)。

答案 3 :(得分:1)

使用jq,可以使用过滤器将数组拆分为其组件:

.[]

然后问题就变成了每个组件要做的事情。如果要将每个组件定向到单独的文件,您可以(例如)将jq与-c选项一起使用,并将结果过滤为awk,然后awk可以将组件分配给不同的文件。参见例如Split JSON File Objects Into Multiple Files

性能考虑因素

有人可能认为调用jq + awk的开销与调用python相比会很高,但是与python + json相比,jq和awk都是轻量级的,正如这些时序(使用Python 2.7.10)所暗示的那样:

time (jq -c  .[] input.json | awk '{print > "doc00" NR ".json";}')
user    0m0.005s
sys     0m0.008s

time python split.py
user    0m0.016s
sys     0m0.046s

答案 4 :(得分:0)

一种方法是使用jq的stream选项并将其管道传递给split命令

jq -cn --stream 'fromstream(1|truncate_stream(inputs))' bigfile.json | split -l $num_of_elements_in_a_file - big_part

每个文件的行数根据您输入num_of_elements_in_a_file中的值而有所不同,

您可以查看此答案Using jq how can I split a very large JSON file into multiple files, each a specific quantity of objects? 参考该页面以讨论如何使用流解析器 https://github.com/stedolan/jq/wiki/FAQ#streaming-json-parser