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

时间:2014-11-05 09:58:53

标签: regex grep gnu

我有这三个文件:

$ cat pattern-ok 
['\-]
$ cat pattern-buggy 
[\-']
$ cat text 
abc'def-ghi

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

$ cat text | grep -f pattern-ok 
abc'def-ghi
$ cat text | grep -f pattern-buggy
grep: Invalid range end

我正在使用:

$ grep --version | head -n 1
grep (GNU grep) 2.20

2 个答案:

答案 0 :(得分:24)

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

你基本上在做

grep "[\-']" file

当您提供要检查的一系列字符时,由grep解释,例如grep "[a-z]" file。但是从\'的范围无效,因此错误。

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

grep "['\-]" file

在这种情况下,您正在寻找文件中的字符'\-

请参阅另一个示例,我想在给定字符串中找到字符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
-

因此,潜在的问题是您在some character块中使用表达式- + another character + []并尝试将其作为字符范围读取在some characteranother character之间。


你怎么解决?

如果你想匹配角色-,只需将其添加到表达式的边缘:作为第一个或最后一个项目。

来自man grep

  

字符类和括号表达式

     

括号表达式是由[和]括起来的字符列表。它   匹配该列表中的任何单个字符;如果是第一个角色   列表是插入符号^然后匹配任何不在其中的字符   列表。例如,正则表达式[0123456789]匹配   任何一个数字。

     

在括号表达式中,范围表达式由两个组成   用连字符分隔的字符。它匹配任何单个字符   使用区域设置对两个角色(包括两个角色)进行排序   整理顺序和字符集。例如,在默认C中   locale,[a-d]相当于[abcd]。许多语言环境排序字符   按字典顺序,在这些语言环境中[a-d]通常是   不等于[abcd];它可能等同于[aBbCcDd]   例。获得支架的传统解释   表达式,您可以通过设置LC_ALL来使用C语言环境   环境变量为值C。

     

最后,预定义了某些命名的字符类   括号表达式,如下。他们的名字不言自明,   它们是[:alnum:],[:alpha:],[:cntrl:],[:digit:],   [:graph:],[:lower:],[:print:],[:punct:],[:space:],[:upper:],   和[:xdigit:]。例如,[[:alnum:]]表示字符类   当前语言环境中的数字和字母。在C语言环境和ASCII中   字符集编码,这与[0-9A-Za-z]相同。 (注意   这些类名中的括号是符号的一部分   名称,并且必须包含在括号内的括号之外   括号表达。)大多数元字符失去了它们的特殊含义   内部括号表达式。要包含文字]放置它   列表中的第一个。同样,要包含一个文字^放置它   除了第一个。 最后,要包含一个文字 - 放置它   最后

答案 1 :(得分:0)

要避免范围值,可以使用fgrep