grep / egrep星号运算符与所有匹配项不匹配

时间:2014-07-18 22:54:16

标签: regex linux macos bash grep

我们取字符串AaAa。我想匹配a s:

$ echo AaAa | grep -o a
a
a

所以它打印每场比赛而不仅仅是第一场比赛。当我在a之后添加星标时,我得到以下内容

$ echo AaAa | grep -o 'a*'
$

为什么grep这次不输出每场比赛?我知道它匹配,因为如果我们删除-o选项,它会打印整行:

$ echo AaAa | grep 'a*'
AaAa

要查看应该匹配的匹配项数,我使用了sed

$ echo AaAa | sed 's/a*/x/g'
xAxAx

替换x的字符串应该是grep -o打印的字符串。所以匹配如下:

  1. 开头的空字符串,用于匹配a零次
  2. 第一个a
  3. 第二个a
  4. 为什么不打印以下内容?

    $ echo AaAa | grep -o 'a*'
    
    a
    a
    $
    

    修改

    以上是使用GNU grep 2.5.1完成的 以下是使用GNU grep 2.6.3

    完成的
    $ echo AaAa | grep -o 'a*'
    a
    a
    $
    

    请注意,它仍然没有在自己的行上打印第一个空字符串。似乎这个bug在这个新版本中得到了部分修复。不应该匹配一个空字符串,就像上面的sed示例一样吗?

2 个答案:

答案 0 :(得分:2)

让我们从这开始:

$ echo AaAa | grep -o 'a*'
$

您提到这是在版本2.5.1上运行的。这似乎是grep中的一个错误,似乎已在2.5.3中修复。

以下是GNU grep development的引用:

2.5.3
=====
Fix the combinations:
 * -i -o
 * --colour -i
 * -o -b
 * -o and zero-width matches
Go through the bug list im my mailbox and fix fixable.
Fix bugs reported with 2.5.2.

-o和零宽度匹配是我们似乎在这里处理的错误。零宽度断言不会消耗字符串中匹配的字符,但它们仍然是断言,因此它们必须匹配。在这种情况下,我们的零宽度断言与字符a零次匹配。

到下一部分:

$ echo AaAa | grep -o 'a*'
a
a
$

我认为你没有在这里得到一个空行的原因只是-o标志不会为零宽度断言打印任何内容。

答案 1 :(得分:1)

您可以使用awk

删除重复项
$ echo AaAa | grep -o a|awk '!x[$0]++'
a