任何一年的简单grep

时间:2013-05-16 23:38:20

标签: regex linux grep escaping digits

我知道我在这里做了一些事情,但在我的Unix / Linux类中给我们的正则表达式备忘单暗示(通过我的阅读)这应该在包含年份的文本文件中找到行(数字从0000到0000) 9999):

grep \d{4} file.txt

为什么它找不到任何东西?这是使用bash,与Windows上的PuTTY和Mac上的终端相同。我试过带括号和引号的变体没有效果。搜索[0-9][0-9][0-9][0-9]有效,但\d{4}似乎无法正常运行。

在相关的说明中,为什么.\+具有我期望的.+效果,而.+只是简单的“不起作用”? (我知道它告诉grep寻找某些东西但我不知道是什么。)也就是说,这似乎是要求“这里有一个或多个角色”而不是“一个角色”的方式其次是加号“。 (这是完成作业的正确方法,老师可以向我解释为什么会这样)并且如何搜索“一个字符后跟加号”?

3 个答案:

答案 0 :(得分:3)

您的备忘单可能表明\d{4}是有效的正则表达式,意思是“四位数”;它可能表示grep在文件中搜索正则表达式。单独考虑,这两个陈述都是正确的。但综合起来,它们具有很强的误导性,因为grep PATTERN FILE期望一种正则表达式(POSIX“基本正则表达式”,BRE),而\d{4}是来自不同的符号一种正则表达式(有时称为“Perl兼容正则表达式”,PCRE,在Perl编程语言之后)。

grep的许多版本都支持-P标志,表明该模式是PCRE而不是BRE;你可以尝试:

grep -P '\d{4}' file.txt

(请注意\d{4}周围的单引号。这些是必要的,因为否则Bash会将\d作为'd'的一种简写,因此实际模式传递给{{ 1}}将是grep,意思是“四个d{4}”而不是“四个数字”。或者,您可以编写d,它以不同的方式解决相同的问题。 )


编辑添加:抱歉,我未能涵盖您问题的第二部分,即grep -P \\d{4} file.txt。所以,根据相关规范, 1 这个:

+

使用grep .+ file.txt 表示“除NUL之外的任何字符”,.表示“实际加号”。所以它确实应该打印包含非初始加号的+行;如果您看到不同的行为,那么您的shell和/或file.txt必须是不一致的。

此外,这:

grep

与上面相同,因为符合要求的POSIX shell(例如Bash)会将grep .\+ file.txt 视为一种写\+的奇特方式,因此+会看到相同的参数像之前一样。 (grep无法知道您输入了grep而不是.\+。)

最后,这个:

.+

(其中grep '.\+' file.txt 实际传递给\)具有未定义的行为:给定的grep实现可以将其视为与grep相同的事物,或者它可以使.+成为一个特殊的符号,意思是“一个或多个”(或其他东西),或者它可以给出错误信息。实际上,GNU实现采用“一个或多个”解释,但其他可能不同。

脚注:

  1. the grep specthe BRE and ERE spec\+规范链接和引用)。同样相关的是the shell spec,因为它是shell决定传递给grep的实际参数。

答案 1 :(得分:2)

默认情况下,grep使用POSIX正则表达式,不包括\d。要使用表达式,需要切换到PCRE(arg -P)

grep -P \\d{4} file.txt 

这将返回file.txt中的每个4位字符串实例。

答案 2 :(得分:2)

如果您的grep版本不支持-P,则以下内容有效:

grep "\d\{4\}" file.txt

关于您的其他问题,使用相同风格的正则表达式,.+将匹配任何字符,后跟+符号。 .\+将匹配任何字符中的一个或多个。