假设文件内容如下:
abc.h hello world
grep "*.h" file
和grep -E "*.h" file
的输出不同。根据我的理解,他们应该是一样的。 *
是正则表达式元字符。输出应该都是abc.h
。
输出
grep "*.h" file # ==> No output
grep -E "*.h" file # ==> abc.h
请帮助澄清这个问题!
答案 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}}将无法编译。