fed*_*man 9 utilities unicode tr
我需要国际化的实用程序,它的作用与tr
:从流中获取字符并将其替换为相应的字符。不是像从低到高这样的特定案例解决方案,而是需要通用案例解决方案。sed
如果可能的话,不要使用 gorillion 管道电话。
请注意,这tr
不适用于 Linux:它转换字节,而不是字符。这对多字节编码失败。
$ tr --version | head -n 1
tr (GNU coreutils) 8.23
$ echo $LC_CTYPE
en_US.UTF-8
$ echo 'Ångstrom' | tr Æ Œ
?ngstrom
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 12
GNUsed
可以处理多字节字符。所以:
$ echo 齯 | sed 'y/齯/ABŒ/'
ABŒ
Run Code Online (Sandbox Code Playgroud)
并不是说 GNUtr
没有国际化,而是它不支持多字节字符(如 UTF-8 语言环境中的非 ASCII 字符)。GNUtr
可以使用Æ
,Œ
只要它们像 iso8859-15 字符集中一样是单字节的。
更多关于如何让 tr 知道非 ascii(unicode) 字符?
无论如何,这与Linux无关,而是关于tr
系统上的实现。该系统是使用 Linux 作为内核还是tr
为 Linux 构建或使用 Linux 内核 API 都无关紧要,因为这部分tr
功能发生在用户空间中。
busyboxtr
和 GNUtr
在为 Linux 构建的软件发行版中最常见,并且不支持多字节字符,但还有其他一些已移植到 Linux 中,例如tr
传家宝工具箱(从 OpenSolaris 移植)或 ast-打开那个做。
请注意,sed
'sy
不支持像a-z
. 另请注意,如果包含的脚本sed 'y/齯/ABŒ/'
是用 UTF-8 字符集编写的,如果在 UTF-8 不是字符集的区域设置中调用,它将不再按预期工作。
另一种方法是使用perl
:
perl -Mopen=locale -Mutf8 -pe 'y/a-z齯/A-ZABŒ/'
Run Code Online (Sandbox Code Playgroud)
上面,perl 代码预计为 UTF-8,但它将处理区域设置编码的输入(并以相同的编码输出)。如果在 UTF-8 语言环境中调用,它会将 UTF-8 Æ
(0xc3 0x86)音译为 UTF -8 Œ
(0xc5 0x92),并在 ISO8859-15 中音译为 0xc6 -> 0xbc。
在大多数 shell 中,即使脚本是在 UTF-8 不是字符集的语言环境中调用的,在单引号内包含这些 UTF-8 字符也应该没问题(一个例外是yash
,如果这些字节不能形成有效字符,则会报错在语言环境中)。但是,如果您使用单引号以外的其他引用,则可能会导致问题。例如,
perl -Mopen=locale -Mutf8 -pe "y/?\`/&'/"
Run Code Online (Sandbox Code Playgroud)
在字符集为 BIG5-HKSCS 的区域设置中会失败,因为\
(0x5c)的编码也恰好包含在其他一些字符中(例如?
:0xa3 0x5c,并且 UTF-8 编码?
恰好以 0xa3 结尾)。
无论如何,不要指望像
perl -Mopen=locale -Mutf8 -pe 'y/Á-?/A-Z/'
Run Code Online (Sandbox Code Playgroud)
致力于消除尖锐的口音。以上其实只是
perl -Mopen=locale -Mutf8 -pe 'y/\x{c1}-\x{179}/\x{41}-\x{5a}/'
Run Code Online (Sandbox Code Playgroud)
也就是说,范围基于 unicode 代码点。因此,在 Unicode中碰巧处于“正确”顺序的非常明确的序列之外,范围将没有用处,例如A-Z
, 0-9
。
如果要删除重音符号,则必须使用更高级的工具,例如:
perl -Mopen=locale -MUnicode::Normalize -pe '
$_ = NFKD($_); s/\x{301}//g; $_ = NFKC($_)'
Run Code Online (Sandbox Code Playgroud)
那就是使用 Unicode 规范化形式来分解字符,去除重音符号(这里是组合形式U+0301
)并重新组合。
另一个用于音译 Unicode 的有用工具uconv
来自ICU。例如,上面的也可以写成:
uconv -x '::NFKD; \u0301>; ::NFKC;'
Run Code Online (Sandbox Code Playgroud)
虽然只适用于 UTF-8 数据。你需要:
iconv -t utf-8 | uconv -x '::NFKD; \u0301>; ::NFKC;' | iconv -f utf-8
Run Code Online (Sandbox Code Playgroud)
能够在用户的语言环境中处理数据。