gpt4 book ai didi

awk 降低以重音符号开头的字符串 - 支持外来字符

转载 作者:行者123 更新时间:2023-12-03 09:16:34 32 4
gpt4 key购买 nike

我有一个文件,其中一行包含此字符串:“Ávila”

我想得到这个输出:“ávila”

问题在于awk的函数tolower仅在字符串不以重音开头时才起作用,而我必须使用awk。

例如,如果我执行 awk 'BEGIN { print tolower("Ávila") }' ,那么我会得到 "Ávila" 而不是 "ávila",这就是我所期望的。

但是如果我执行awk 'BEGIN { print tolower("Castellón") }',那么我会得到"castellón"

最佳答案

对于给定的awk要与非 ASCII 字符(外文字母)正常工作,它必须尊重事件区域设置的字符编码,如(有效)LC_CTYPE 中所反射(reflect)的那样。设置(运行 locale 查看它)。

如今,大多数语言环境都使用 UTF-8 编码,这是一种多字节按需编码,在 ASCII 范围内为单字节,并使用 2 到 4 个字节来表示所有其他 Unicode 字符。
因此,对于给定的awk要实现识别非 ASCII(重音、外文)字母,它必须能够将多个字节识别为单个字符

主要awk实现

  • GNU Awk ( gawk ),某些 Linux 发行版上的默认设置
  • BSD awk ,也用于 OS X
  • Mawk ( mawk ),基于 Debian 的 Linux 发行版(例如 Ubuntu)的默认设置

只有 GNU Awk 可以正确处理 UTF8 编码的字符(如果在语言环境中指定的话,可能还有任何其他编码):

$ echo ÁvilA | gawk '{print tolower($0)}'
ávila # both Á and A lowercased

相反,如果您明确希望将字符处理仅限于 ASCII,请在前面加上 LC_CTYPE=C :

$ echo ÁvilA | LC_CTYPE=C gawk '{print tolower($0)}'
Ávila # only ASCII char. A lowercased

实用建议:

  • 确定您的默认实现 awk,运行awk --version .

    • 对于 Mawk,您会收到一条错误消息,因为它仅支持使用 -W version 打印版本信息。 ,但该错误消息将包含单词 mawk .
  • 如果可能的话,安装并使用 GNU Awk(并可选择将其设置为默认值 awk );它适用于大多数类 Unix 平台;例如:

    • 在基于 Debian 的平台(例如 Ubuntu)上:sudo apt-get install gawk
    • 在 OS X 上,使用 Homebrew :brew install gawk .
  • 如果您必须使用 BSD Awk 或 Mawk,请使用上面的 LC_CTYPE=C方法确保多字节 UTF-8 字符至少通过而不进行修改。[1],但是外来字母不会被识别为字母(因此在本例中不会被小写)。


[1] OS X 上的 BSD Awk 和 Mawk(奇怪的是后者在 Linux 上没有)按如下方式处理 UTF-8 编码字符:

  • 每个字节都被错误地解释为它自己的字符
  • 如果在忽略高位之后,结果字节值落在 ASCII 大写字母的范围内,32添加到原始字节值以获得对应的小写字母。

在本例中,这意味着:

  • Á是 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-900x41-0x5a ),因此该字节保持原样。

  • 实际上,第一个字节是从 0xC3 修改的。至0xE3 ,而第二个字节保持不变;自 0xC3 0x81不是正确的 UTF-8 编码字符,终端将打印 ?而是发出信号。

关于awk 降低以重音符号开头的字符串 - 支持外来字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37033989/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com