grep 中的 Unicode 字符标识



我发现了一个非常奇怪的行为,想知道是否有人知道是什么原因造成的。解释起来很长,所以感谢您的耐心等待。我正在Windows环境中运行一个bash脚本,通过cygwin调用。在其中,我基本上想在文件中找到任何行,这些行的字符在我定义的特定字母表中找不到,非常简单。由于我使用的是 Unicode 字符,因此我已设置

$ LC_ALL=en_US.UTF-8

我有一个名为"files.txt"的文件,其中包含以下内容:

$ cat files.txt
đđđ
üüü

我用普通字符和 Unicode 字符定义我的字母表:

$ ALPHABET=$(printf %s {a..z} $(printf "u0161") $(printf "u010d"))
$ echo $ALPHABET
abcdefghijklmnopqrstuvwxyzšč
$ grep -v "^[$ALPHABET ]*$" files.txt
đđđ
üüü

不出所料。问题尤其出现在字符"Ñ"(\u00d1)与"đ"(\u0111)的组合中:

$ ALPHABET=$(printf %s {a..z} $(printf "u00d1") $(printf "u0161") $(printf "u010d"))
$ echo $ALPHABET
abcdefghijklmnopqrstuvwxyzÑšč
$ grep -v "^[$ALPHABET ]*$" files.txt
üüü

有趣的是,在某些情况下,如果还添加了其他 Unicode 字符,才会发生这种情况。唯一不变的是"Ñ"必须在那里。

$ ALPHABET=$(printf %s {a..z} $(printf "u00d1"))
$ echo $ALPHABET
abcdefghijklmnopqrstuvwxyzÑ
$ grep -v "^[$ALPHABET ]*$" files.txt
đđđ
üüü
$ ALPHABET=$(printf %s {a..z} $(printf "u00d1") a $(printf "u010d"))
$ echo $ALPHABET
abcdefghijklmnopqrstuvwxyzÑač
$ grep -v "^[$ALPHABET ]*$" files.txt
üüü
$ ALPHABET=$(printf %s {a..z} $(printf "u010d") $(printf "u00d1"))
$ echo $ALPHABET
abcdefghijklmnopqrstuvwxyzčÑ
$ grep -v "^[$ALPHABET ]*$" files.txt
üüü
$ ALPHABET=$(printf %s {a..z} $(printf "u010d") $(printf "u010c"))
$ echo $ALPHABET
abcdefghijklmnopqrstuvwxyzčČ
$ grep -v "^[$ALPHABET ]*$" files.txt
đđđ
üüü
$ ALPHABET=$(printf %s {a..z} $(printf "u00d1") $(printf "u00e1") $(printf "u00c9"))
$ echo $ALPHABET
abcdefghijklmnopqrstuvwxyzÑáÉ
$ grep -v "^[$ALPHABET ]*$" files.txt
đđđ
üüü

我尝试了各种组合和排序,但无法准确确定哪种类型的组合决定了 grep 决定"đ"在模式中。我唯一发现的是"Ñ"必须存在以及其他一些其他 unicode 字符的排列方式,但我无法弄清楚这种其他排列必须是什么。

最后,如果我直接在cygwin终端中执行这些命令,事情就会正常工作。仅当我通过 Windows 批处理"C:\Tools\cygwin64\bin\bash.exe%SCRIPT%"调用此脚本的执行时,才会发生此行为。

有谁知道会发生什么?谢谢,非常感谢。

感谢 @n.m. 提供正确的答案!实际上,LC_ALL必须出口。一旦我这样做了,行为就符合预期,并且在我尝试的所有不同配置中都没有将 đ 识别为模式的一部分。所以而不是

$ LC_ALL=en_US.UTF-8

用:

$ export LC_ALL=en_US.UTF-8

不知道为什么会这样(因为所有命令都在同一终端中按顺序运行),但我想如果这就是它工作的原因,那就继续吧。感谢大家的帮助和建议,我意识到环境不容易复制。

相关内容

  • 没有找到相关文章

最新更新