【问题标题】:does utf-8 encoding messes file globbing and grep'ing?utf-8 编码是否会混淆文件 globbing 和 grep'ing?
【发布时间】:2010-09-21 22:06:55
【问题描述】:

我正在玩 bash,体验 utf-8 编码。我是 unicode 新手。 下面的命令(嗯,他们的输出)让我吃惊:

$ 语言环境
LANG="fr_FR.UTF-8"
LC_COLLATE="fr_FR.UTF-8"
LC_CTYPE="fr_FR.UTF-8"
LC_MESSAGES="fr_FR.UTF-8"
LC_MONETARY="fr_FR.UTF-8"
LC_NUMERIC="fr_FR.UTF-8"
LC_TIME="fr_FR.UTF-8"
LC_ALL=
$ printf '1\né\n12\n123\n' | egrep '^(.|...)$'
1
é
12
$ 触摸 1 é 12 123
$ ls | egrep '^(.|...)$'
1
123

好的。两个 egrep 过滤带有一个或三个字符的行。它们的输入非常相似,但输出与字符 é 不同。有什么解释吗?

关于我的环境的更多细节:

$ unname -a
达尔文 macbook-pro-de-admin-6.local 10.4.0 达尔文内核版本 10.4.0:2010 年 4 月 23 日星期五 18:28:53 PDT;根目录:xnu-1504.7.4~1/RELEASE_I386 i386
$ egrep -V
egrep (GNU grep) 2.5.1

版权所有 1988、1992-1999、2000、2001 Free Software Foundation, Inc.
这是免费软件;查看复制条件的来源。没有
保修单;甚至不是为了适销性或特定用途的适用性。

【问题讨论】:

  • 比较ls | hexdump -C printf '1\né\n12\n123\n' | hexdump -C的输出。如果您没有hexdump,请尝试hd
  • 输出与 hexdump 不同:printf 给出 0xC3 0xA9 而 ls 为 é 吐出 0x65 0xCC 0x81。我会尝试从这里更深入。谢谢

标签: encoding utf-8 grep filenames


【解决方案1】:

当您使用单字符通配符时,任何可变长度编码都可能与不了解编码的工具混淆,并考虑字节而不是字符(因为该工具假定字节=字符)。如果您使用文字字符,那么对于 UTF-8,这无关紧要,因为 UTF-8 的结构会阻止字符中间的匹配(假设编码正确)。

至少 一些 版本的 grep 应该支持 UTF-8,根据http://mailman.uib.no/public/corpora/2006-December/003760.html,只要设置了适当的 LANG,GNU grep 2.5.1 及更高版本就包含在其中。但是,如果您使用旧版本或 GNU grep 以外的其他东西,这可能是问题的原因,因为 é 是一个两字节字符 (0xC3 0xA9)。

编辑:根据您最近的评论,您的 grep 可能是 Unicode 感知的,但它不会执行任何形式的 Unicode normalization(老实说,我真的不希望它这样做)。

0x65 0xCC 0x81 是一个 e,后跟 COMBINING ACUTE ACCENT (U+0301)。这实际上是两个字符,但由于组合字符的语义,它被呈现为一个。然后这会导致 grep 将其检测为两个字符;一个用于 e,一个用于重音。

似乎分解的 Unicode 是文件名实际存储在文件系统中的方式 - 否则,您可以存储出于所有意图和目的具有完全相同名称但仅在组合使用方面不同的文件字符。

【讨论】:

    猜你喜欢
    • 2020-01-28
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多