我使用curl
获得一些URL响应,这是JSON响应,它包含unicode转义的国家字符,如\u0144 (ń)
和\u00f3 (ó)
。
我如何将它们转换为UTF-8或任何其他编码保存到文件?
我不知道你使用的是哪种发行版,但是应该包含uni2ascii 。
$ sudo apt-get install uni2ascii
它只依赖于libc6,所以它是一个轻量级的解决方案(在Ubuntu上uni2ascii i386 4.18-2是55,0 kB)!
然后使用它:
$ echo 'Character 1: \u0144, Character 2: \u00f3' | ascii2uni -a U -q Character 1: ń, Character 2: ó
可能会有点丑,但echo -e
应该这样做:
echo -en "$(curl $URL)"
-e
解释转义, -n
抑制通常会添加的换行符。
注意: \u
转义工作在bash内建的echo
,而不是/usr/bin/echo
。
正如在注释中指出的那样,这是bash 4.2+,4.2.x有一个处理0x00ff / 17值(0x80-0xff)的bug。
我发现JDK中的native2ascii是最好的方法:
native2ascii -encoding UTF-8 -reverse src.txt dest.txt
详细描述在这里: http : //docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/native2ascii.html
更新:自JDK9以来不再可用: https ://bugs.openjdk.java.net/browse/JDK-8074431
假设\u
后面总是紧跟着4个十六进制数字:
#!/usr/bin/perl use strict; use warnings; binmode(STDOUT, ':utf8'); while (<>) { s/\\u([0-9a-fA-F]{4})/chr(hex($1))/eg; print; }
binmode
将标准输出转换为UTF-8模式。 s...
命令将每个出现的\u
后跟4个十六进制数字替换为相应的字符。 e
后缀会导致替换被评估为表达式而不是视为字符串; g
说,要取代所有的事件,而不是只是第一次。
您可以将上述内容保存到$PATH
某个文件中(不要忘记chmod +x
)。 它将标准输入(或命令行中命名的一个或多个文件)过滤到标准输出。
使用/usr/bin/printf "\u0160ini\u010di Ho\u0161i - A\u017e sa skon\u010d\u00ed zima"
来获得适当的Unicode到/usr/bin/printf "\u0160ini\u010di Ho\u0161i - A\u017e sa skon\u010d\u00ed zima"
转换。
不要依赖正则表达式:JSON有\u
转义和非BMP代码点的一些奇怪的角落案例。 (具体来说,JSON将使用两个 \u
转义符对一个代码点进行编码)如果您假定1个转义序列转换为1个代码点,则注定会出现在这样的文本上。
从您选择的语言中使用完整的JSON解析器相当强大:
$ echo '["foo bar \u0144\n"]' | python -c 'import json, sys; sys.stdout.write(json.load(sys.stdin)[0].encode("utf-8"))'
这实际上只是将数据提供给这个简短的Python脚本:
import json import sys data = json.load(sys.stdin) data = data[0] # change this to find your string in the JSON sys.stdout.write(data.encode('utf-8'))
从中你可以保存为foo.py
和调用curl ... | foo.py
curl ... | foo.py
在这个问题上会打破大多数其他尝试的例子是"\ud83d\udca3"
:
% printf '"\\ud83d\\udca3"' | python2 -c 'import json, sys; sys.stdout.write(json.load(sys.stdin)[0].encode("utf-8"))'; echo 💣 # echo will result in corrupt output: % echo -e $(printf '"\\ud83d\\udca3"') " " # native2ascii won't even try (this is correct for its intended use case, however, just not ours): % printf '"\\ud83d\\udca3"' | native2ascii -encoding utf-8 -reverse "\ud83d\udca3"
在Windows上工作,也应该在* nix上工作。 使用Python 2。
#!/usr/bin/env python from __future__ import unicode_literals import sys import json import codecs def unescape_json(fname_in, fname_out): with file(fname_in, 'rb') as fin: js = json.load(fin) with codecs.open(fname_out, 'wb', 'utf-8') as fout: json.dump(js, fout, ensure_ascii=False) def usage(): print "Converts all \\uXXXX codes in json into utf-8" print "Usage: .py infile outfile" sys.exit(1) def main(): try: fname_in, fname_out = sys.argv[1:] except Exception: usage() unescape_json(fname_in, fname_out) print "Done." if __name__ == '__main__': main()