grep中的Unicode字符标识

时间:2016-03-09 13:57:15

标签: bash unicode cygwin

我发现了一种非常奇怪的行为,并且想知道是否有人知道是什么原因造成的。这需要解释,所以感谢您的耐心等待。 我在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%”调用此脚本的执行,则只会出现此问题。

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

1 个答案:

答案 0 :(得分:0)

感谢@ n.m.提供正确的答案! 实际上,必须导出LC_ALL。一旦我做了,行为就像预期的那样,并且在我尝试过的所有不同配置中,đ都没有被认为是模式的一部分。 而不是

$ LC_ALL=en_US.UTF-8

使用:

$ export LC_ALL=en_US.UTF-8

不确定为什么会出现这种情况(因为所有命令都在同一个终端中顺序运行),但我想如果这就是它的工作原理,那么就去吧。 感谢大家的帮助和建议,我意识到环境不容易重现。