如何使用*nix中的控制台工具将\ uXXXX unicode转换为UTF-8

Krz*_*lny 51 unix linux unicode encoding json

curl用来获取一些URL响应,它是JSON响应,它包含unicode转义的国家字符,如\u0144 (?)\u00f3 (ó).

如何将它们转换为UTF-8或任何其他编码保存到文件中?

Kev*_*vin 41

可能有点难看,但echo -e应该这样做:

echo -en "$(curl $URL)"
Run Code Online (Sandbox Code Playgroud)

-e解释转义,-n抑制换行echo通常会添加.

注意:\u转义在内置的bash中工作echo,但不是/usr/bin/echo.

正如评论中指出的那样,这是bash 4.2+,4.2.x有一个错误处理0x00ff/17值(0x80-0xff).


Krz*_*lny 36

我发现JDK的native2ascii是最好的方法:

native2ascii -encoding UTF-8 -reverse src.txt dest.txt
Run Code Online (Sandbox Code Playgroud)

详细说明如下:http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/native2ascii.html

更新: 自JDK9以来不再可用:https://bugs.openjdk.java.net/browse/JDK-8074431


rap*_*elh 35

我不知道你使用的是哪个发行版,但是应该包括uni2ascii.

$ sudo apt-get install uni2ascii
Run Code Online (Sandbox Code Playgroud)

它只依赖于libc6,所以它是一个轻量级的解决方案(un2ascii i386 4.18-2在Ubuntu上是55 kB)!

然后使用它:

$ echo 'Character 1: \u0144, Character 2: \u00f3' | ascii2uni -a U -q
Character 1: ?, Character 2: ó
Run Code Online (Sandbox Code Playgroud)


Kei*_*son 20

假设\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;
}
Run Code Online (Sandbox Code Playgroud)

binmode放标准输出为UTF-8模式.该s...命令用\u相应的字符替换每次出现后跟4个十六进制数字.所述e后缀导致更换,以进行评价作为表达,而不是作为一个字符串处理; 在g说要全部替换,而不仅仅是第一.

您可以将上述内容保存到您的某个文件中$PATH(不要忘记chmod +x).它将标准输入(或命令行上指定的一个或多个文件)过滤为标准输出.


Tha*_*tos 12

不要依赖正则表达式: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"))'
Run Code Online (Sandbox Code Playgroud)

这真的只是将数据提供给这个简短的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'))
Run Code Online (Sandbox Code Playgroud)

您可以从中保存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"
Run Code Online (Sandbox Code Playgroud)

  • 很奇怪你四年后重新审视这个问题.正如您所暗示的那样,这个答案并没有重新发明轮子:事实上它使用了Python的内置JSON解析器.此线程中的许多其他答案都试图强制使用不适用于此目的的工具,因此会在某些有效输入上发出错误输出.考虑JSON编码的值`"\ ud83d\udca9"`; 使用`echo`和你的`native2ascii`解决方案的最高投票解决方案都不会处理此输入. (3认同)

and*_*rej 9

用于/usr/bin/printf "\u0160ini\u010di Ho\u0161i - A\u017e sa skon\u010d\u00ed zima"获得正确的unicode-to-utf8转换.


Smi*_*nth 5

现在我有了最好的答案!使用jq

视窗:

type in.json | jq > out.json
Run Code Online (Sandbox Code Playgroud)

卢尼克斯:

cat in.json | jq > out.json
Run Code Online (Sandbox Code Playgroud)

使用perl / python的答案肯定更快。如果没有参数,它将格式化json并将\ uXXXX转换为utf8。它也可以用于执行json查询。很好的工具!


Rob*_*ade 5

使用bPOSIX 强制的转换说明符:

\n\n
\n

b应支持附加转换说明符字符 ,如下所示。该参数应被视为可以包含反斜杠转义序列的字符串。
\n — http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html

\n
\n\n
expand_escape_sequences() {\n  printf %b "$1"\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

测试:

\n\n
expand_escape_sequences() {\n  printf %b "$1"\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

注意:如果删除%b格式说明符,百分号将导致错误,例如:

\n\n
-bash: printf: `O\': invalid format character\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 bash 的内置函数printf/usr/bin/printf我的 Linux 发行版(Fedora 29)上测试成功。

\n\n
\n\n

2019-04-17 更新:我的解决方案假设 unicode 转义类似于\\uxxxxand \\Uxxxxxxxx;BMP 之外的 unicode 字符需要后者。然而,OP 的问题涉及 JSON 流。JSON 的 unicode 转义序列使用 UTF16,这需要 BMP 之外的代理对。

\n\n

考虑 unicode 字符(\'GRINNING FACE WITH SMILING EYES\' (U+1F601))。\\U该字符的转义序列是:\\U0001F601。您可以使用 POSIX 强制%b说明符打印它,如下所示:

\n\n
s=\'\\u0160ini\\u010di Ho\\u0161i - A\\u017e sa skon\\u010d\\u00ed zima A percent sign % OK?\'\nexpand_escape_sequences "$s"\n\n# output: \xc5\xa0ini\xc4\x8di Ho\xc5\xa1i - A\xc5\xbe sa skon\xc4\x8d\xc3\xad zima A percent sign % OK?\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,在 JSON 中,该字符的转义序列涉及 UTF16 代理项对:\\uD83D\\uDE01

\n\n

对于在 shell 级别操作 JSON 流,该jq工具非常出色:

\n\n
-bash: printf: `O\': invalid format character\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,我现在不再考虑我的答案,并认可 Smit Johnth 的答案,将其用作jq最佳答案。

\n