【发布时间】:2011-10-11 14:35:55
【问题描述】:
我正在做一些日常的 grepping,突然发现一些看似微不足道的事情不起作用:
$ echo T | grep [A-Z]
不匹配。
为什么T不在A-Z范围内?
我稍微改变了正则表达式:
$ echo T | grep [A-Y]
一场比赛!
哇! T 在 A-Y 内而不在 A-Z 内如何?
显然这是因为我的环境设置为爱沙尼亚语言环境,其中 Y 位于字母表的末尾,而 Z 位于中间的某个位置:ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY
$ echo $LANG
et_EE.UTF-8
这一切让我有点震惊。 99% 的时间我 grep 计算机代码,而不是爱沙尼亚文学。我一直在错误地使用 grep 吗?我过去因此而犯了哪些错误?
在尝试了几件事后,我得出了以下解决方案:
$ echo T | LANG=C grep [A-Z]
这是使 grep 独立于语言环境的推荐方法吗?
还有更多...定义这样的别名是否安全:
$ alias grep="LANG=C grep"
PS.我也想知道为什么像[A-Z]这样的字符范围首先依赖于语言环境,而\w似乎不受语言环境的影响(尽管手册上说@987654328 @ 等同于 [[:alnum:]] - 但我发现后者取决于语言环境,而 \w 则不)。
【问题讨论】:
-
请再试一次,但请引用您的表达式
grep '[A-Z]',以确保外壳不会扩展它。 -
加引号和不加引号对我来说都是一样的。
-
工作方式相同,只是因为您没有一个名为 A 到 Z 的文件。shell 尝试扩展 [A-Z],但没有找到任何内容,然后就不管它了。使用引号始终将模式传递给 grep。
-
谢谢,我实际上并不知道 Bash 支持扩展这种东西。但我实际上一直在引用 grep 参数——我只是想我会不使用它们以缩短代码示例。现在又变聪明了。
-
问题“这是使 grep 语言环境独立的推荐方法吗?”不合适。
grep必须使用 some 语言环境;它根本无法在没有任何语言环境的情况下运行。我想你可能想改写问“这是如何让 grep 使用我习惯的旧 ASCII 语言环境吗?”,这确实有一个答案:是的。LC_ALL=C将为您提供旧的 ASCII 字符集和整理顺序。LC_COLLATE=C将允许完整的本地语言环境字符集,但要确保它以熟悉的 ASCII 方式排序。这就是你想要的吗?