【问题标题】:How can I render UTF-16BE in command line?如何在命令行中呈现 UTF-16BE?
【发布时间】:2012-12-14 06:12:49
【问题描述】:

我经常遇到一个表示 UTF-16BE 的字符串,例如 \u0444\u0430\u0439\u043b,它会正确地呈现为 файл

我想知道:是否有一种简单的方法可以使用 sed 或其他命令行工具以 UTF-16BE(或简单地 UTF-16BE 中的输入字符串)“呈现”文本文件,例如上面的那个?

另见this related question

【问题讨论】:

  • 字符串实际上是用 UTF-16BE 编码的,每个 Unicode 字符有 2 个字节,还是像您在问题中显示的那样是带有反斜杠字符的 ASCII 字符串?
  • 那个字符串不是 UTF-16BE。请更新您的问题。
  • 如果我理解您的 "render" 表示法,您的意思是一种将六字节转义序列转换为 UTF-16BE 字符的简单方法,除了能够实际上 在控制台上渲染。您可以使用选择性地解释 JSON 字符串字符转义的脚本或小程序来执行此操作。如果这是唯一被“渲染”的符号,我很乐意花不到一个小时的时间来编写这样的程序。 在你的情况下它在很大程度上取决于对 Keith Thompson 问题的回答。请详细说明您的问题。

标签: ubuntu unicode sed command-line-interface


【解决方案1】:

假设文本实际上是用 UTF-16BE 编码的(而不是像您在问题中显示的那样,作为包含反斜杠和 'u' 字符的 ASCII 字符串),您可以使用 iconv 命令。

假设您的语言环境设置为处理 UTF-8 输出:

iconv -f utf-16be -t utf-8 [input-file]

编辑:

根据您的 cmets,您所拥有的根本不是 UTF-16BE;它显然是纯 ASCII,使用 \u.... 语法对 Unicode 代码点进行编码。这不是iconv 识别的格式(据我所知)。

您应该编辑您的问题,删除对 UTF-16BE 的所有引用,并更准确地解释您实际拥有哪些数据,以及您想用它做什么。这些字符串是从哪里来的?它们是存储在文本文件中,还是来自其他来源(例如,某个程序的输出)?输入是否完全\u.... 组成,还是与其他数据混合在一起?您的区域设置是否配置为正确显示 UTF-8?

如果您有一个包含"\u0444\u0430\u0439\u043b"(即24 个ASCII 字符)的字符串,那么printf 命令应该可以工作——如果您使用的是足够新的printf 版本。 p>

printf 既是一个 shell 内置命令,也是一个外部命令,/usr/bin/printf,是 GNU coreutils 包的一部分。

以下适用于我的系统:

$ s='\u0444\u0430\u0439\u043b'
$ printf "$s\n"
файл

或者您可以使用%b 格式(这是特定于printf 命令的;C 的printf() 函数不这样做),它解释参数字符串中的反斜杠转义(通常它们只在格式字符串):

$ printf "%b\n" "$s"
файл

在另一个系统上,使用旧版本的 bash,内置的 printf 无法识别 \u 转义 -- 但 /usr/bin/printf 可以。看来 coreutils printf 命令比 bash 更早地获得了对 \u 转义的支持。

$ s='\u0444\u0430\u0439\u043b'
$ printf "$s\n"
\u0444\u0430\u0439\u043b
$ printf "%b\n" "$s"
\u0444\u0430\u0439\u043b
$ /usr/bin/printf "$s\n"
файл
$ /usr/bin/printf "%b\n" "$s"
файл

所有这些都假设您在变量中有'\u0444\u0430\u0439\u043b' 字符串。如果它在一个文件中,您可以将文件内容放入一个 shell 变量中,一次可能是一行,但这不是最好的解决方案。在这种情况下,这个 Perl 脚本应该可以完成这项工作;它将输入复制到标准输出,将\u....序列替换为相应的Unicode字符,以UTF-8编码;输入可以是在命令行中命名的一个或多个文件,也可以是标准输入(如果调用时不带参数)。

#!/usr/bin/perl

use strict;
use warnings;

use utf8;
binmode(STDOUT, ":utf8");

while (<>) {
    s/\\u([\da-fA-F]{4})/chr(hex($1))/eg;
    print;
}

再次,编辑您的问题,使其反映您的实际问题并删除对 UTF-16BE 的任何引用。

【讨论】:

  • 它是 UTF-16BE,但每个前面都有一个 \u,就像我的例子一样。那还有别的名字吗?
  • 如果你有'例如,6个字节的值'\''u''0''4''4''4',那不是UTF-16BE;它是纯 ASCII,恰好是 Unicode 代码点的人类可读表示。相同代码点的 UTF-16BE 表示将正好是 2 个字节,其值为 '0x04''0x44'。如果您有一个包含 UTF-16BE 的 文件,请尝试使用十六进制编辑器或转储命令检查它;此类文件通常在 MS Windows 上创建。
  • 知道了。就我而言,它只是字符串形式。当它是这样的文本时有什么解决方案吗? \u0444\u0430\u0439\u043b? printfecho -e 不起作用。
  • @Strapakowsky:查看我的更新答案——请更新您的问题。
【解决方案2】:

简单地做:

echo -e "\u0444\u0430\u0439\u043b"

请注意,您可能需要将环境变量 LANG 设置为 utf-8

export LANG="en_US.UTF-8"

正如 Keith Thompson 所指出的,使用printf 可能会更好;所以,你会有:

printf "\u0444\u0430\u0439\u043b"

对于以上两个选项,输出为:

файл

【讨论】:

  • echo -e 并不总是具备这种能力。 printf 命令更有可能起作用。
  • 你假设输入是包含反斜杠和'u'字符的ASCII,我怀疑不是这样。
  • 这不是OP提供的数据吗?
  • 它们都不适合我。输出与输入相同。我错过了什么吗?
  • 您可能正在寻找 Keith Thompson 提供的答案
猜你喜欢
  • 2019-06-03
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
相关资源
最近更新 更多