我在玩bash,体验utf-8编码。我对unicode还不熟悉。下面的命令(嗯,它们的输出)让我感到惊讶:
$ locale 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é\n 12\n 123\n’AC.26 egrep‘^(.|.)$’ 1 请注意: 12 1é12 123 $ ls \ egrep‘(.|.)$’ 1 123
好的。两个白鹭过滤一行或三个字符。它们的输入非常相似,但输出与字符不同。有什么解释吗?
关于我的环境的更多细节:
$ uname -a 达尔文macbook-6本地10.4.0达尔文内核版本10.4.0: Fri 4月23日18:28:53 PDT 2010;根:xnu-1504.7.4~1/RELEASE 386 i386 $ egrep -V egrep (GNU grep) 2.5.1版权1988年、1992-1999、2000、2001年自由软件基金会。 这是免费软件,请参阅复制条件的源代码。没有 保修;即使是适销性或适合某一特定用途。
发布于 2010-09-21 22:19:46
当您使用单字符通配符时,任何可变长度编码都会扰乱那些不知道编码的工具,并考虑字节,而不是字符(因为该工具假定为byte=character)。如果您使用文字字符,那么对于UTF-8,这并不重要,因为UTF-8的结构会阻止字符中间的匹配(假设适当的编码)。
至少有一些版本的grep应该是UTF-8知道,根据http://mailman.uib.no/public/corpora/2006-December/003760.html,GNUgrep2.5.1和更高版本包含在那里,只要设置了适当的LANG。但是,如果您使用的是旧版本,或者grep以外的其他版本,这可能是问题的原因,因为é是一个两个字节的字符(0xC3 0xA9)。
编辑:根据您最近的评论,您的grep可能是Unicode感知的,但它不执行任何类型的Unicode规范化 (老实说,我不希望它这么做)。
0x650xCC0x81是e,其次是合并急性口音(U+0301)。这实际上是两个字符,但由于组合字符的语义,它被呈现为一个字符。这将导致grep将其检测为两个字符:一个用于e,另一个用于重音。
分解后的Unicode很可能是文件名实际存储在您的文件系统中的方式--否则,您可以存储的文件,出于所有意图和目的,都具有完全相同的名称,但仅在组合字符的使用上有所不同。
https://stackoverflow.com/questions/3764864
复制相似问题