如何在 bash 中将 UTF-8 txt 文件转换为全部大写?

VPe*_*ric 11 unicode locale tr text

我有一些 UTF-8 .txt 文件,我想将它们转换为全部大写。如果它只是 ASCII,我可以使用:

tr [:lower:] [:upper:]
Run Code Online (Sandbox Code Playgroud)

但由于我正在使用变音符号和其他东西,它似乎不起作用。我想如果我设置了适当的语言环境,它可能会起作用,但我需要这个脚本是可移植的。

Sté*_*las 16

所有的:

tr '[:lower:]' '[:upper:]'
Run Code Online (Sandbox Code Playgroud)

(不要忘记引号,否则如果有一个名为:, l, ...的文件或r在当前目录中,那将不起作用)或:

awk '{print toupper($0)}'
Run Code Online (Sandbox Code Playgroud)

或者:

dd conv=ucase
Run Code Online (Sandbox Code Playgroud)

旨在根据当前语言环境中定义的规则将字符转换为大写。然而,即使语言环境使用 UTF-8 作为字符集并明确定义了从小写到大写的转换,至少 GNU dd、 GNUtr和mawk(awk例如 Ubuntu 上的默认值)不遵循它们。此外,除了or 之外,没有指定语言环境的标准方法,因此,如果您想将 UTF-8 文件可移植地转换为大写,而不管当前语言环境如何,那么标准工具箱就不太走运了。CPOSIX

通常,为了可移植性,您最好的选择可能是 perl:

$ echo l?sšc?t?zž | PERLIO=:utf8 perl -pe '$_=uc'
L?SŠC?T?ZŽ
Run Code Online (Sandbox Code Playgroud)

现在,您需要注意并不是每个人都同意特定字符的大写版本是什么。

例如,在土耳其语语言环境中,大写字母i不是I,而是?( <U0130>)。这里使用传家宝工具箱tr而不是 GNU tr:

$ echo ií | LC_ALL=C.UTF-8 tr '[:lower:]' '[:upper:]'
IÍ
$ echo ií | LC_ALL=tr_TR.UTF-8 tr '[:lower:]' '[:upper:]'
?Í
Run Code Online (Sandbox Code Playgroud)

在我的系统上,perlto-upper 转换是在 中定义的/usr/share/perl/5.14/unicore/To/Upper.pl,我发现它toupper()在C.UTF8语言环境中对来自 GNU libc 的几个字符的行为有所不同,例如,perl更准确。例如perl正确转换? 到?, GNU libc (2.17) 没有。


slm*_*slm 7

我认为你可以用awk它的toupper功能来做到这一点。

\n\n

例如

\n\n

不适用于 GNU tr:

\n\n
$ echo l\xc4\xbes\xc5\xa1c\xc4\x8dt\xc5\xa5z\xc5\xbe | tr '[:lower:]' '[:upper:]'\nL\xc4\xbeS\xc5\xa1C\xc4\x8dT\xc5\xa5Z\xc5\xbe\n
Run Code Online (Sandbox Code Playgroud)\n\n

与 GNU 一起工作awk:

\n\n
$ echo l\xc4\xbes\xc5\xa1c\xc4\x8dt\xc5\xa5z\xc5\xbe | awk '{ print toupper($0) }'\nL\xc4\xbdS\xc5\xa0C\xc4\x8cT\xc5\xa4Z\xc5\xbd\n
Run Code Online (Sandbox Code Playgroud)\n