为什么在同一个文件中输出'grep'* .h“'和'grep -E”* .h“'的不同输出

时间:2016-04-24 14:10:29

标签: regex linux grep gnu

假设文件内容如下:

abc.h  
hello world

grep "*.h" filegrep -E "*.h" file的输出不同。根据我的理解,他们应该是一样的。 *是正则表达式元字符。输出应该都是abc.h

输出

grep "*.h" file     # ==> No output
grep -E "*.h" file  # ==> abc.h

请帮助澄清这个问题!

3 个答案:

答案 0 :(得分:3)

/login不应匹配任何一行。如果是这样,那是因为你的特定grep的扩展正则表达式引擎以不同的方式处理边界或量词。您可能会在GNU grep中看到这种奇怪的行为,但BSD grep会正确地报告*.h

您可能意味着grep: repetition-operator operand invalid,无论您使用BRE还是ERE引擎,都会匹配这两行。如果您只想匹配提供的语料库中的.*h,则需要:

abc.h

这将匹配任何带有文字句点后跟字母grep '\.h' /tmp/foo 的行。您甚至可能希望将其锚定在行尾,以确保您不会错误地捕获h之类的文本。例如:

foo abc.h bar

答案 1 :(得分:3)

POSIX定义(POSIX)regular expressions的行为,并定义基本正则表达式(BRE)和扩展正则表达式(ERE)。使用grep -E需要ERE;如果没有-E,则会获得BRE(-F没有正则表达式。)

BRE中*的POSIX定义说:

  

*       <asterisk>应该是特殊的,除非使用:

     
      
  • 在括号表达式

  • 中   
  • 作为整个BRE的第一个字符(在初始'^'之后,如果有的话)

  •   

ERE中*的POSIX定义说:

  

*+?{       <asterisk><plus-sign><question-mark><left-brace>应该是特殊的,除非在括号表达式中使用(请参阅RE括号表达式)。以下任何一种用途都会产生不确定的结果:

     
      
  • 如果这些字符首先出现在ERE中,或者紧跟<vertical-line><circumflex><left-parenthesis>
  •   

在问题中:

  • 使用grep '*.h'正在使用BRE,*首先显示,因此它不是特殊字符;它匹配*后跟任何字符,后跟h

    This would be matched *Zh because the * and the h are separated by one character
    This would not be matched because the * and the h are not separated by one character
    
  • 使用grep -E '*.h'调用未定义的行为。任何结果都有效。

为了可靠地匹配abc.h和以.h结尾的其他字母数字文件名,您可以使用以下内容:

grep '[[:alnum:]]\.h'

在此上下文中没有特别需要使用*;如果你这样做,你可以写下其中一个:

grep '^[[:alnum:]][[:alnum:]]*\.h$'
grep '^[[:alnum:]]\{1,\}\.h$'

这些行查找由一个或多个字母数字组成的行,后跟.h以及行尾。如果你不喜欢字符类表达式表示法([:alnum:]部分),你可以写这个:

grep '^[a-zA-Z0-9][a-zA-Z0-9]*\.h$'
grep '^[a-zA-Z0-9]\{1,\}\.h$'

如果您愿意,可以添加下划线:

grep '^[[:alnum:]_][[:alnum:]_]*\.h$'
grep '^[a-zA-Z0-9_][a-zA-Z0-9_]*\.h$'

您可以使用扩展的正则表达式,如:

grep '^[[:alnum:]_]+\.h$'
grep '^[a-zA-Z0-9_]+\.h$'

等等。选项很多!

答案 2 :(得分:0)

MyService - 扩展正则表达式,其中-E表示前一项将匹配零次或多次

*(默认) - 基本正则表达式,其中-G仅表示*字符

* - Perl正则表达式,其中-P表示与*中的相同,但-E无法编译,因为没有任何内容可以重复(*.h之前没有字符{ {1}})。使用*

libpcre

因此ldd /bin/grep linux-vdso.so.1 (0x00007ffefddd4000) libpcre.so.1 => /lib64/libpcre.so.1 (0x0000003bd8a00000) libc.so.6 => /lib64/libc.so.6 (0x0000003bd6a00000) libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003bd7200000) /lib64/ld-linux-x86-64.so.2 (0x0000003bd6600000) 将匹配任何具有grep -E "*.h"序列的字符串; .h将匹配任何具有grep -G "*.h"序列的字符串; <{1}}将无法编译。