鉴于我有以下文件:
{
"title": {
"ger": "Komödie" (utf8, encoded as c3 b6)
},
"files": [
{
"filename": "Kom�die" (latin1, encoded as f6)
}
]
}
(如果您尝试复制粘贴,可能看起来会有所不同)
这是由于应用程序错误而发生的,我无法修复生成这些文件的源。
我现在尝试修复文件名字段的字符集,可以有多个。我首先尝试使用 jq (单字段):
value="$(jq '.files[0].filename' <in.txt | iconv -f latin1 -t utf-8)"
jq --arg f "$value" '.files[0].filename = $f' <in.txt
但是 jq 将整个文件解释为 utf-8,这会损坏单个 f6 字符。
我想在python中找到解决方案,但同样,输入在linux中默认解释为utf-8。我尝试使用“ascii”,但这不允许字符 >= 128。
现在,我想我找到了一种方法,但是 json 序列化器转义了所有字符。由于我(故意)使用了错误的字符集,因此转义序列也是垃圾。
#!/usr/bin/python3
import sys
import io
import json
with open('in.txt', encoding='latin1') as fh:
j = json.load(fh)
for f in j['files']:
f['filename'] = f['filename'].encode('utf-8').decode('latin1') # might be wrong, couldn't test
with open('out.txt', 'w', encoding='latin1') as fh:
json.dump(j, fh)
我该怎么做才能达到预期的结果,一个干净的非转义的 utf-8 json 文件?
到目前为止我发现的解决方法是根本不使用 json。它之所以有效,是因为我知道这些文件的结构非常好,并且我可以通过静态文本模式轻松找到断线(带有文件名的断线):
#!/usr/bin/python3
with open('in.txt', encoding='latin1') as fh:
lines = fh.readlines()
# change the encoding of all filename: lines and keep everything else
lines = [line.encode('utf-8').decode('latin1') if line.startswith("\t\t\t\"filename\": \"") else line for line in lines]
with open('out.txt', 'w', encoding='latin1') as fh:
fh.writelines(lines)
输出:
{
"title": {
"ger": "Komödie"
},
"files": [
{
"filename": "Komödie"
}
]
}