如何从文件中读取独立的缩进 JSON 对象(JSON 行但缩进)?
How to read independent indented JSON objects from a file (JSON Lines but indented)?
我有一个大文件存储彼此相邻的 JSON 个对象,这些对象应该是 JSON Lines 格式,但我犯了一个大错误,将它们缩进存储(因此每个对象占用多个行而不是一行)。
它具有这种格式(注意对象之间缺少 ,
):
{
"contributors": null,
"coordinates": null,
"created_at": "Mon Sep 21 11:51:09 +0000 2020",
"entities": {
"hashtags": [],
"symbols": []
}
}
{
"contributors": null,
"coordinates": null,
"created_at": "Mon Sep 21 11:51:09 +0000 2020",
"entities": {
"hashtags": [],
"symbols": []
}
}
所有项目都可以使用非缩进文件(每行一个 JSON),我的想法是将这个大 JSON 文件转换为非缩进格式,但我正在努力找到读取文件的方法。
我尝试转换的代码是:
import json
import sys
import os
FILE_INPUT='PathToTheBigFile'
FILE_OUTPUT='PathToConvertedFile'
tweets_list = []
for line in open(FILE_INPUT, 'r', encoding='utf-8'):
tweets_list.append(json.loads(line))
with open(FILE_OUTPUT, 'a') as outfile:
for tweet in tweets_list:
outfile.write(json.dumps(tweet) + '\n')
并且它适用于非缩进文件(它基本上是复制文件)但是对于缩进文件这个 JSONDecodeError
被引发:
json.decoder.JSONDecodeError:
Expecting property name enclosed in double quotes: line 2 column 1 (char 2)
我曾尝试在 Python 中做到这一点,也考虑过使用 Linux 和 tr 命令或类似的东西来做到这一点,但我还没有找到办法。我可能会尝试使用其他语言。
关于如何操作有什么建议吗?
问题是您的 JSON string/file 中有 2 个彼此相邻的对象。如果您可以在它们之间添加一个逗号(并将整个内容包装在 []
中),那么您可以将其解析为一个对象数组。
阅读文件时尝试这样的操作:
import re
with open(FILE_INPUT, 'r', encoding='utf-8') as file:
json_data = re.sub(r"}\s*{", "},{", file.read())
tweets_list.extend(json.loads("[" + json_data + "]"))
然后,在编写文件时,您应该将其保存为一组对象,而不是每行一个对象。没有理由多次调用 json.dumps
。
with open(FILE_OUTPUT, 'w') as outfile:
outfile.write(json.dumps(tweets_list))
请注意,我使用的是 'w'
,因此它正在覆盖文件。您将首先读取 整个 文件,以便您可以追加到数组并将整个文件写回。
如果您要将数据附加到文件,然后再次读回该文件,我建议您尝试 csv
而不是 json
。您可以轻松地将行附加到 csv
文件,而不必担心稍后再解析它。或者甚至 xml
文件也可以在这里工作。
我有一个大文件存储彼此相邻的 JSON 个对象,这些对象应该是 JSON Lines 格式,但我犯了一个大错误,将它们缩进存储(因此每个对象占用多个行而不是一行)。
它具有这种格式(注意对象之间缺少 ,
):
{
"contributors": null,
"coordinates": null,
"created_at": "Mon Sep 21 11:51:09 +0000 2020",
"entities": {
"hashtags": [],
"symbols": []
}
}
{
"contributors": null,
"coordinates": null,
"created_at": "Mon Sep 21 11:51:09 +0000 2020",
"entities": {
"hashtags": [],
"symbols": []
}
}
所有项目都可以使用非缩进文件(每行一个 JSON),我的想法是将这个大 JSON 文件转换为非缩进格式,但我正在努力找到读取文件的方法。 我尝试转换的代码是:
import json
import sys
import os
FILE_INPUT='PathToTheBigFile'
FILE_OUTPUT='PathToConvertedFile'
tweets_list = []
for line in open(FILE_INPUT, 'r', encoding='utf-8'):
tweets_list.append(json.loads(line))
with open(FILE_OUTPUT, 'a') as outfile:
for tweet in tweets_list:
outfile.write(json.dumps(tweet) + '\n')
并且它适用于非缩进文件(它基本上是复制文件)但是对于缩进文件这个 JSONDecodeError
被引发:
json.decoder.JSONDecodeError:
Expecting property name enclosed in double quotes: line 2 column 1 (char 2)
我曾尝试在 Python 中做到这一点,也考虑过使用 Linux 和 tr 命令或类似的东西来做到这一点,但我还没有找到办法。我可能会尝试使用其他语言。
关于如何操作有什么建议吗?
问题是您的 JSON string/file 中有 2 个彼此相邻的对象。如果您可以在它们之间添加一个逗号(并将整个内容包装在 []
中),那么您可以将其解析为一个对象数组。
阅读文件时尝试这样的操作:
import re
with open(FILE_INPUT, 'r', encoding='utf-8') as file:
json_data = re.sub(r"}\s*{", "},{", file.read())
tweets_list.extend(json.loads("[" + json_data + "]"))
然后,在编写文件时,您应该将其保存为一组对象,而不是每行一个对象。没有理由多次调用 json.dumps
。
with open(FILE_OUTPUT, 'w') as outfile:
outfile.write(json.dumps(tweets_list))
请注意,我使用的是 'w'
,因此它正在覆盖文件。您将首先读取 整个 文件,以便您可以追加到数组并将整个文件写回。
如果您要将数据附加到文件,然后再次读回该文件,我建议您尝试 csv
而不是 json
。您可以轻松地将行附加到 csv
文件,而不必担心稍后再解析它。或者甚至 xml
文件也可以在这里工作。