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


10

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

tr [:lower:] [:upper:]

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

Answers:


14

所有的:

tr '[:lower:]' '[:upper:]'

(不要忘了引号,否则这是行不通的,如果有一个称为文件:l......或r在当前目录)或:

awk '{print toupper($0)}'

要么:

dd conv=ucase

用于根据当前语言环境中定义的规则将字符转换为大写。但是,即使语言环境使用UTF-8作为字符集并明确定义了从小写到大写的转换,至少GNU dd,GNU trmawkawk例如,Ubuntu上的默认设置)也不会遵循它们。此外,除了或之外,没有其他标准的方法来指定语言环境,因此,如果您希望将UTF-8文件可移植地转换为大写字母而不管当前语言环境如何,那么标准工具箱就不那么幸运了。CPOSIX

通常,出于便携性考虑,最好的选择是perl:

$ echo lľsšcčtťzž | PERLIO=:utf8 perl -pe '$_=uc'
LĽSŠCČTŤZŽ

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

例如,在土耳其语区域设置中,大写字母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:]'
İÍ

在我的系统上,perlto-upper转换是在中定义的/usr/share/perl/5.14/unicore/To/Upper.pl,例如,toupper()C.UTF8语言环境中,perl它在GNU libc的几个字符上的行为有所不同,从而更加准确。例如,perl正确地将correctly转换为Ɀ,而GNU libc(2.17)却没有。


对于它的价值,我正在使用捷克字母(并且您使用的示例实际上是斯洛伐克语),其中所有大写字母均已明确定义,但是语言环境设置可能是C而不是捷克语,所以这是一个问题。Perl已在此工具链中使用,因此添加其他用途可能并不算太糟。谢谢您的详细解释,顺便说一句!
VPeric

3

我认为您可以使用awk它及其toupper功能来做到这一点。

例如

不适用于GNU tr

$ echo lľsšcčtťzž | tr '[:lower:]' '[:upper:]'
LľSšCčTťZž

与GNU一起使用awk

$ echo lľsšcčtťzž | awk '{ print toupper($0) }'
LĽSŠCČTŤZŽ

@StephaneChazelas-谢谢,我更改了失败的示例。
slm

这取决于当前的语言环境和trawk实现。例如tr,根据当前的语言环境,大多数会在UTF8语言环境中正确转换字符,而GNU tr不会。mawk没有。
斯特凡Chazelas

1
实际上,在FreeBSD(9.1)上则相反。它的工作原理同tr,但与awk
斯特凡Chazelas

@StephaneChazelas-我不熟悉差异8-)。有人不满意,想知道为什么吗?
slm

2

这适用于OS X,tr但不适用于GNU tr

tr '[:lower:]' '[:upper:]'

这适用于,gawk但不适用于mawknawk/usr/bin/awk在OS X中):

awk '{print toupper($0)}'

另一种选择是使用GNU sed

sed 's/./\u&/g'

在Bash 4.0和更高版本中,您还可以使用^^参数扩展:

while IFS= read -r l;do printf %s\\n "${l^^}";done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.