提取单个JSON对象

时间:2016-07-05 11:08:38

标签: python json bash shell unix

我有以下JSON文件,我从API获取。

{"Key-1":"Value-1",
"Key-2":[{"Value-2"::Child_Value-1","Value-3":"Child_Value-2"}]
}
{"Key-21":"Value-21",
"Key-22":[{"Value-22":"Child_Value-21","Value-23":"Child_Value-22"}]
}
{"Key-31":"Value-31",
"Key-32":[{"Value-32":"Child_Value-31","Value-33":"Child_Value-32"}]
}

我知道这不符合JSON格式,但我想要实现的是我想要提取每个单独的对象并将它们存储在一个单独的文件中。

例如file1.json应该包含 -

[{"Key-1":"Value-1",
    "Key-2":[{"Value-2":"Child_Value-1","Value-3":"Child_Value-2"}]
    }]

file2.json应包含 -

[{"Key-21":"Value-21",
    "Key-22":[{"Value-22":"Child_Value-21","Value-23":"Child_Value-22"}]
    }]

我试图通过python和shell脚本来做这件事,但它并没有把我带到任何地方。在python / shell中是否有一个很好的库可以提供帮助。我对使用的语言有限制(python,shell-script)

3 个答案:

答案 0 :(得分:1)

这里的内容非常缓慢,无法处理数据中的错误,但可能会有效。它是一个生成器,可以找到第一个' {'然后是下一个'}',并尝试将其间的位解析为JSON。如果失败,它会查找下一个'}'然后再试一次。它产生成功解析的位。

import json

def generate_json_dictionaries(s):
    opening = s.find('{')
    while opening != -1:
        possible_closing = opening
        while True:
            possible_closing = s.find('}', start=possible_closing+1)
            if possible_closing == -1: return  # Data incomplete
            try:
                j = json.loads(s[opening:possible_closing+1])
                yield j
                break
            except ValueError:
                pass
        opening = s.find('{', start=possible_closing+1)  # Next start

未经测试。

答案 1 :(得分:0)

这正是您的问题所要求的(虽然我怀疑它实际上并不是您想要的)

filecount = 0
newfilecontents = ''

with open('junksrc.txt', mode='r', encoding='utf-8') as src:
    srclines = src.readlines()
    for line in srclines:
        if '{"Key' in line:
            newfilecontents = '[' + line
        if '}]' in line:
            newfilecontents = newfilecontents + '    ' + line + '    }]\n'
            filecount += 1
            filename = 'junkdest' + str(filecount) + '.json'
            with open(filename, mode='w', encoding='utf-8') as dest:
                dest.write(newfilecontents)

答案 2 :(得分:0)

如果你得到jq,你可以将数据预处理成一个易于被标准库的JSON解析器解析的表单:

$ jq -s '.' tmp.json
[
  {
    "Key-1": "Value-1",
    "Key-2": [
      {
        "Value-2": "Child_Value-1",
        "Value-3": "Child_Value-2"
      }
    ]
  },
  {
    "Key-21": "Value-21",
    "Key-22": [
      {
        "Value-22": "Child_Value-21",
        "Value-23": "Child_Value-22"
      }
    ]
  },
  {
    "Key-31": "Value-31",
    "Key-32": [
      {
        "Value-32": "Child_Value-31",
        "Value-33": "Child_Value-32"
      }
    ]
  }
]

jq可以识别有效的顶级对象流,就像您在这里一样。 -s选项告诉jq在进一步处理之前将它们全部放在一个顶级数组中。