Grep的"无效范围结束" - 错误或功能?

Mic*_*Rus 12 regex grep gnu

我有这三个文件:

$ cat pattern-ok 
['\-]
$ cat pattern-buggy 
[\-']
$ cat text 
abc'def-ghi
Run Code Online (Sandbox Code Playgroud)

现在,以下是我不知道的错误或正则表达式功能?

$ cat text | grep -f pattern-ok 
abc'def-ghi
$ cat text | grep -f pattern-buggy
grep: Invalid range end
Run Code Online (Sandbox Code Playgroud)

我正在使用:

$ grep --version | head -n 1
grep (GNU grep) 2.20
Run Code Online (Sandbox Code Playgroud)

fed*_*qui 27

这是因为您在其他字符中使用连字符,因此将其grep理解为范围,这恰好是无效的.

你基本上是在做

grep "[\-']" file
Run Code Online (Sandbox Code Playgroud)

这可以通过grep提供要检查的一系列字符来解释,例如grep "[a-z]" file.但是,从范围\'是无效的,因此错误.

为什么另一个正在工作?你可能会问自己.因为你在做的是:

grep "['\-]" file
Run Code Online (Sandbox Code Playgroud)

在这种情况下,你正在寻找任一字符',\-在文件中.

看到它的另一个例子,在这里我想找到的字符a,-3一个给定的字符串:

$ echo "23-2" | grep -o '[a-3]'
grep: Invalid range end
$ echo "23-2" | grep -o '[a3-]'
3
-
$ echo "23-2" | grep -o '[a3\-]'
3
-
Run Code Online (Sandbox Code Playgroud)

因此,根本问题是所使用的表达some character+ -+ another character一个内[]块和它试图读作之间的字符范围some characteranother character.


你怎么解决它?

如果要匹配字符-,请将其添加到表达式的边缘:作为第一个或最后一个项目.

来自man grep:

字符类和括号表达式

括号表达式是由[和]括起来的字符列表.它匹配该列表中的任何单个字符; 如果列表的第一个字符是插入符号^那么它匹配列表中没有的任何字符.例如,正则表达式[0123456789]匹配任何单个数字.

在括号表达式中,范围表达式由两个用连字符分隔的字符组成.它匹配使用区域设置的整理顺序和字符集在两个字符之间进行排序的任何单个字符.例如,在默认的C语言环境中,[ad]等同于[abcd].许多语言环境按字典顺序对字符进行排序,在这些语言环境中[ad]通常不等同于[abcd]; 例如,它可能等同于[aBbCcDd].要获得括号表达式的传统解释,可以通过将LC_ALL环境变量设置为值C来使用C语言环境.

最后,某些命名的字符类在括号表达式中预定义,如下所示.他们的名字是自我解释的,他们是[:alnum:],[:alpha:],[:cntrl:],[:digit:],[:graph:],[:lower:],[:print:] ,[:punct:],[:space:],[:upper:]和[:xdigit:].例如,[[:alnum:]]表示当前语言环境中数字和字母的字符类.在C语言环境和ASCII字符集编码中,这与[0-9A-Za-z]相同.(请注意,这些类名中的括号是符号名称的一部分,除括号括起括号表达式的括号外,还必须包括它们.)大多数元字符在括号表达式中失去其特殊含义.要包含文字,请将其放在列表中的第一位.同样,要包含一个文字^将它放在任何地方,但首先. 最后,要包含一个文字 - 将它放在最后.

  • 所以*没有办法*只是逃避它并放在`[]`组中的任何地方?:哦很奇怪.在我的生命中,我一直在使用它像`[abc\-def]`并且不知道它的真正含义.谢谢. (2认同)
  • 具体来说,从“反斜杠”到“单引号”的范围无效,因为“反斜杠”的 ASCII 代码*大于*“单引号”的 ASCII 代码。范围“az”是可以的,因为从 ASCII 角度来看,a 比 z 小。 (2认同)

小智 7

为避免范围值,您可以使用fgrep.