awk tolower 以重音符开头的字符串 - 支持外来字符
Awk tolower a string that starts with an accent - support for foreign characters
我有一个文件,其中一行包含此字符串:"Ávila"
我想得到这个输出:"ávila".
问题是awk的tolower函数只有在字符串不以accent开头的情况下才有效,我必须用awk。
例如,如果我执行 awk 'BEGIN { print tolower("Ávila") }',那么我会得到 "Ávila" 而不是 “ávila”,这正是我所期望的。
但是如果我执行 awk 'BEGIN { print tolower("Castellón") }' 那么我会得到 "castellón"
对于给定的 awk
实现,要正确处理非 ASCII 字符(外来字母),它必须遵守活动语言环境的字符编码,如(有效)LC_CTYPE
设置( 运行 locale
看看吧)。
如今,大多数语言环境都使用 UTF-8 编码,这是一种多字节按需编码,在 ASCII 范围内是单字节,并使用 2 到 4 个字节来表示所有其他 Unicode 字符。
因此,对于给定的 awk
实现来识别非 ASCII(重音,外语)字母,它必须能够将 多个字节 识别为 单个字符.
在主要 awk
实现中,
- GNU Awk (
gawk
),some Linux distros 上的默认设置
- BSD
awk
,也用于 OS X
- Mawk (
mawk
),基于 Debian 的 Linux 发行版的默认设置,例如 Ubuntu
仅 GNU Awk 正确处理 UTF8 编码的字符(如果在语言环境中指定,则可能是任何其他编码):
$ echo ÁvilA | gawk '{print tolower([=10=])}'
ávila # both Á and A lowercased
相反,如果您明确希望将字符处理限制为仅使用 ASCII,请在前面添加 LC_CTYPE=C
:
$ echo ÁvilA | LC_CTYPE=C gawk '{print tolower([=11=])}'
Ávila # only ASCII char. A lowercased
实用建议:
要确定您的默认 awk
是什么实现, 运行 awk --version
.
- 在 Mawk 的情况下,您会收到一条错误消息,因为它仅支持使用
-W version
打印版本信息,但该错误消息将包含单词 mawk
.
If 可能,安装并使用 GNU Awk(并可选择将其设为默认 awk
);它适用于大多数类 Unix 平台;例如:
- 在基于 Debian 的平台上,例如 Ubuntu:
sudo apt-get install gawk
- 在 OS X 上,使用 Homebrew:
brew install gawk
。
如果您必须使用 BSD Awk 或 Mawk,请使用上述 LC_CTYPE=C
方法 以 确保多byte 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-90
, 0x41-0x5a
), 所以字节保持原样。
实际上,第一个字节由0xC3
修改为0xE3
,而第二个字节保持不变;由于 0xC3 0x81
不是 正确的 UTF-8 编码字符,终端将打印 ?
而不是发出信号。
我试着对你的回复发表评论,这是正确的,但我需要能够格式化我添加的内容,否则,它会变得乱码。
超级有用,我想为那些有大写问题的人添加以下内容:
bash-3.2$ echo "TOMÀS VICENÇ ROMÀ" |LC_CTYPE=C gawk '{ print tolower([=10=])}'
tomÀs vicenÇ romÀ
bash-3.2$ echo "TOMÀS VICENÇ ROMÀ" |LC_CTYPE=C gawk '{ print [=10=]}'|tr '[:upper:]' '[:lower:]'
tomàs vicenç romà
我有一个文件,其中一行包含此字符串:"Ávila"
我想得到这个输出:"ávila".
问题是awk的tolower函数只有在字符串不以accent开头的情况下才有效,我必须用awk。
例如,如果我执行 awk 'BEGIN { print tolower("Ávila") }',那么我会得到 "Ávila" 而不是 “ávila”,这正是我所期望的。
但是如果我执行 awk 'BEGIN { print tolower("Castellón") }' 那么我会得到 "castellón"
对于给定的 awk
实现,要正确处理非 ASCII 字符(外来字母),它必须遵守活动语言环境的字符编码,如(有效)LC_CTYPE
设置( 运行 locale
看看吧)。
如今,大多数语言环境都使用 UTF-8 编码,这是一种多字节按需编码,在 ASCII 范围内是单字节,并使用 2 到 4 个字节来表示所有其他 Unicode 字符。
因此,对于给定的 awk
实现来识别非 ASCII(重音,外语)字母,它必须能够将 多个字节 识别为 单个字符.
在主要 awk
实现中,
- GNU Awk (
gawk
),some Linux distros 上的默认设置
- BSD
awk
,也用于 OS X - Mawk (
mawk
),基于 Debian 的 Linux 发行版的默认设置,例如 Ubuntu
仅 GNU Awk 正确处理 UTF8 编码的字符(如果在语言环境中指定,则可能是任何其他编码):
$ echo ÁvilA | gawk '{print tolower([=10=])}'
ávila # both Á and A lowercased
相反,如果您明确希望将字符处理限制为仅使用 ASCII,请在前面添加 LC_CTYPE=C
:
$ echo ÁvilA | LC_CTYPE=C gawk '{print tolower([=11=])}'
Ávila # only ASCII char. A lowercased
实用建议:
要确定您的默认
awk
是什么实现, 运行awk --version
.- 在 Mawk 的情况下,您会收到一条错误消息,因为它仅支持使用
-W version
打印版本信息,但该错误消息将包含单词mawk
.
- 在 Mawk 的情况下,您会收到一条错误消息,因为它仅支持使用
If 可能,安装并使用 GNU Awk(并可选择将其设为默认
awk
);它适用于大多数类 Unix 平台;例如:- 在基于 Debian 的平台上,例如 Ubuntu:
sudo apt-get install gawk
- 在 OS X 上,使用 Homebrew:
brew install gawk
。
- 在基于 Debian 的平台上,例如 Ubuntu:
如果您必须使用 BSD Awk 或 Mawk,请使用上述
LC_CTYPE=C
方法 以 确保多byte 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-90
,0x41-0x5a
), 所以字节保持原样。实际上,第一个字节由
0xC3
修改为0xE3
,而第二个字节保持不变;由于0xC3 0x81
不是 正确的 UTF-8 编码字符,终端将打印?
而不是发出信号。
我试着对你的回复发表评论,这是正确的,但我需要能够格式化我添加的内容,否则,它会变得乱码。
超级有用,我想为那些有大写问题的人添加以下内容:
bash-3.2$ echo "TOMÀS VICENÇ ROMÀ" |LC_CTYPE=C gawk '{ print tolower([=10=])}'
tomÀs vicenÇ romÀ
bash-3.2$ echo "TOMÀS VICENÇ ROMÀ" |LC_CTYPE=C gawk '{ print [=10=]}'|tr '[:upper:]' '[:lower:]'
tomàs vicenç romà