Awk tolower以重音开头的字符串 - 支持外来字符

时间:2016-05-04 17:07:56

标签: awk character-encoding diacritics

我有一个带有此字符串的文件:“Ávila”

我希望得到这样的结果:“ávila”

问题是awk的函数 tolower 仅在字符串不以重音开头时才有效,我必须使用awk。

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

但如果我 awk'BEGIN {print tolower(“Castellón”)}'那么我会“castellón”

2 个答案:

答案 0 :(得分:3)

对于给定awk实现与非ASCII字符(外来字母)一起正常工作,它必须遵守活动区域设置的字符编码,如(有效)LC_CTYPE设置中所反映的那样(运行{ {1}}看到它。)

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

主要awk实施

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

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

mawk

相反,如果您明确希望将字符处理限制为仅限ASCII,请添加$ echo ÁvilA | gawk '{print tolower($0)}' ávila # both Á and A lowercased

LC_CTYPE=C

实用建议:

  • 确定您的默认$ echo ÁvilA | LC_CTYPE=C gawk '{print tolower($0)}' Ávila # only ASCII char. A lowercased 的实施方式,请运行awk

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

    • 在基于Debian的平台上,例如Ubuntu:awk
    • 在OS X上,使用Homebrewsudo apt-get install gawk
  • 如果您必须使用BSD Awk或Mawk,请使用上述brew install gawk方法确保多字节UTF-8字符至少< em>通过而不经修改。 [1] ,但外国字母不会被识别为字母(因此不会小写,在这种情况下)。

[1] OS X上的BSD Awk和Mawk(后者奇怪地在Linux上)将UTF-8编码的字符视为如下:

  • 每个字节被错误地解释为自己的字符
  • 如果忽略高位后,生成的字节值落入ASCII大写字母范围,LC_CTYPE=C将添加到原始字节值获得小写的对应物。

在手头的情况下,这意味着:

  • 32是Unicode代码点Á,其UTF-8编码是 2字节序列U+00C1

    < / LI>
  • 0xC3 0x81:删除高位(0xC3)会产生0xC3 & 0x7F,其被解释为ASCII字母0x43C({ {1}})因此被添加到原始值,产生320x20)。

  • 0xE3:删除高位(0xC3 + 0x20)会产生0x81,其不在ASCII大写字母范围内(0x81 & 0x7F,{{1 }}),所以字节保持原样。

  • 实际上,第一个字节从0x1修改为65-90,而第二个字节保持不变;由于0x41-0x5a 是一个正确的UTF-8编码字符,终端将打印0xC3而不是发出信号。

答案 1 :(得分:0)

我试着评论你的回复,这是正确的,但我需要能够格式化我添加的内容,否则,它会变成乱码。

超级有用,我想为那些有大写问题的人添加以下内容:

bash-3.2$ echo "TOMÀS VICENÇ ROMÀ" |LC_CTYPE=C gawk '{ print tolower($0)}'

tomÀs vicenÇ romÀ


bash-3.2$ echo "TOMÀS VICENÇ ROMÀ" |LC_CTYPE=C gawk '{ print $0}'|tr '[:upper:]' '[:lower:]'

tomàs vicenç romà