Bash(grep)正则表达式意外执行

时间:2013-01-15 14:41:36

标签: regex bash shell grep

我有一个文本文件,其中包含dd/mm/yyyy形式的日期(例如2012年12月20日)。

我正在尝试使用grep来解析日期并在终端中显示它,并且它成功了, 直到我遇到某个案件:

这些是我的测试用例:

  • grep -E "\d*"返回20/12/2012
  • grep -E "\d*/"返回20/12/2012
  • grep -E "\d*/\d*"返回20/12/2012
  • grep -E "\d*/\d*/"返回 没有
  • grep -E "\d+"也会返回 没有

有人可以向我解释为什么我会出现这种意想不到的行为吗?

编辑 :如果我将"(弱引号)替换为'(强引号),我会得到相同的行为。

4 个答案:

答案 0 :(得分:10)

Bash's Extended regex无法识别您使用的语法(\d)。

使用grep -P代替使用Perl正则表达式(PCRE)。例如:

grep -P "\d+/\d+/\d+" input.txt
grep -P "\d{2}/\d{2}/\d{4}" input.txt  # more restrictive

或者,要坚持使用扩展正则表达式,请使用[0-9]代替\d

grep -E "[0-9]+/[0-9]+/[0-9]" input.txt
grep -E "[0-9]{2}/[0-9]{2}/[0-9]{4}" input.txt  # more restrictive

答案 1 :(得分:4)

您也可以使用-P代替-E,它允许grep使用PCRE语法

grep -P "\d+/\d+" file

也有效。

答案 2 :(得分:2)

grepegrep / grep -E无法识别\d。你的前三个模式工作的原因是因为星号使\d可选。它实际上没有找到。

使用[0-9][[:digit:]]

答案 3 :(得分:2)

为了帮助解决这种情况,-o标志可能会有所帮助,因为它只显示该行的匹配部分。使用原始表达式:

grep -Eo "\d*"什么都不返回 - 这是一个线索,\ d没有做你想象的那样。

grep -Eo "\d*/"返回/(两次) - 确认\ d在斜杠不匹配时。

正如其他人所指出的那样,-P标志通过识别“\ d”来解决问题,但为了澄清爆炸药丸的答案,你也可以使用-E如下:

grep -Eo "[[:digit:]]*/[[:digit:]]*/"返回20/12 /

编辑:根据@ shawn-chin的评论(谢谢!),可以类似地使用--color来突出显示匹配的行部分,同时仍然显示整行:

grep -E --color "[[:digit:]]*/[[:digit:]]*/"返回 20/12 / 2012(此处无法使用颜色,但粗体“20/12 /”部分会显示颜色)