use*_*883 2 awk diacritics character-encoding
我有一个文件,其中一行包含此字符串:“\xc3\x81vila”
\n\n我想得到这个输出:"\xc3\xa1vila"。
\n\n问题是awk 的tolower函数仅在字符串不以重音开头时才起作用,而我必须使用 awk。
\n\n例如,如果我执行awk \'BEGIN { print tolower("\xc3\x81vila") }\'然后我得到"\xc3\x81vila"而不是"\xc3\xa1vila",这就是我所期望的。
\n\n但是如果我执行awk \'BEGIN { print tolower("Castell\xc3\xb3n") }\'然后我得到"castell\xc3\xb3n"
\n为了使给定的awk实现能够正确地处理非 ASCII 字符(外文字母),它必须尊重活动区域设置的字符编码,如(有效)设置中所反映的LC_CTYPE(运行locale以查看它)。
如今,大多数语言环境都使用 UTF-8 编码,这是一种多字节按需编码,在 ASCII 范围内为单字节,并使用 2 到 4 个字节来表示所有其他 Unicode 字符。
\n因此,对于awk识别非 ASCII(重音、外文)字母的给定实现,它必须能够将多个字节识别为单个字符。
在主要的awk实施中,
gawk上的默认设置awk,也用于 OS Xmawk),基于 Debian 的 Linux 发行版(例如 Ubuntu)的默认设置只有GNU Awk 可以正确处理 UTF8 编码的字符(如果在语言环境中指定,也可能是任何其他编码):
\n\n$ echo \xc3\x81vilA | gawk \'{print tolower($0)}\'\n\xc3\xa1vila # both \xc3\x81 and A lowercased\nRun Code Online (Sandbox Code Playgroud)\n\n相反,如果您明确希望将字符处理限制为仅 ASCII,请在前面添加LC_CTYPE=C:
$ echo \xc3\x81vilA | LC_CTYPE=C gawk \'{print tolower($0)}\'\n\xc3\x81vila # only ASCII char. A lowercased\nRun Code Online (Sandbox Code Playgroud)\n\n实用建议:
\n\n要确定您的默认实现awk是什么,请运行awk --version。
-W version,但该错误消息将包含单词mawk。如果可能,安装并使用 GNU Awk(并可选择将其设为默认值awk);它适用于大多数类 Unix 平台;例如:
sudo apt-get install gawkbrew install gawk .如果必须使用 BSD Awk 或 Mawk,请使用上述LC_CTYPE=C方法来确保多字节 UTF-8 字符至少在不进行修改的情况下通过。[1],但外来字母不会被识别为字母(因此在这种情况下不会被小写)。
[1] OS X 上的 BSD Awk 和 Mawk(奇怪的是后者不在Linux 上)按如下方式处理 UTF-8 编码字符:
\n\n32字节值相加,得到对应的小写字母。在本例中,这意味着:
\n\n\xc3\x81是 Unicode 代码点U+00C1,其 UTF-8 编码是2 字节序列: 0xC3 0x81。
0xC3:删除高位 ( 0xC3 & 0x7F) 得到0x43,它被解释为 ASCII 字母C,因此将32( 0x20) 添加到原始值,得到0xE3( 0xC3 + 0x20)。
0x81:删除高位 ( 0x81 & 0x7F) 会产生0x1,它不在 ASCII 大写字母 ( 65-90, 0x41-0x5a) 的范围内,因此该字节保持原样。
实际上,第一个字节从 修改为0xC3,0xE3而第二个字节保持不变;由于0xC3 0x81不是正确的UTF-8 编码字符,终端将打印?来表示这一点。
| 归档时间: |
|
| 查看次数: |
1677 次 |
| 最近记录: |