Grep完全匹配不起作用

时间:2016-03-27 02:07:46

标签: bash shell

我有一个属性文件

myprop2=this is with <br/>

当我尝试grep <br>

grep "^myprop.*=.`*<br>*`" MyProject.properties | xargs | cut -d '=' -f 1

为什么找到 myprop2

注意:我找到了<br>而不是<br/>(没有结束标记)

2 个答案:

答案 0 :(得分:2)

右角括号之后的*使其在匹配中被安全忽略0次或更多次。我认为你的意思是...>.*

此外,使用预见可以消除一些管道

grep -oP "myprop.(?==.*<br>.*)" file

将在没有xargs和cut

的情况下提供相同的内容

答案 1 :(得分:1)

您的双引号字符串包含*<br>*command substitution的实例)周围的反引号,这意味着Bash将尝试执行 { {1}}作为命令 - 由于各种原因而失败 - 并将表达式扩展为该命令生成的stdout输出。

由于该失败的命令不产生 stdout 输出,*<br>*表达式扩展为null(空)字符串,这意味着`...`将看到以下字符串文字:
grep

任何以^myprop.*=."开头的行,最后跟一个myprop和至少1个字符。匹配此正则表达式,无论后面是什么 - 这就是=行匹配的原因。

如果要将反引号匹配为文字,您可以将它们转义为myprop2或使用单个引用的字符串代替。<登记/> (如果您认为\`字符必须在带引号的字符串中进行转义以便按字面处理:它们不会 - 只有不带引号的使用需要转义。)

但是,karakfa's helpful answer正确地暗示即使您没有将*括在反引号中,使用重复符号*<br>*>后也意味着任何 *的实例数 - 包括无 - 匹配。

由于>默认情况下匹配行的子字符串,因此这有效地匹配行的任何剩余部分,包括以grep开头的字符串,因此匹配/>

因此,虽然使用<br/>代替>代替.*确实解决了这个问题,但是没有必要 - 用*结束正则表达式。

他的 GNU >解决方案(因为只有GNU grep支持grep选项才能启用对PCREs的支持,以启用外观等功能 - 因此可以简化为:

-P

注意使用单个引号,这是不需要插值的字符串的更好选择,以保证它们按原样使用。

如果使用GNU grep -oP 'myprop.*(?==.*<br>)' MyProject.properties 不是一个选项,请使用(请注意,没有理由使用grep):

xargs

或者,使用grep '^myprop.*=.*<br>' MyProject.properties | cut -d '=' -f 1

awk

或者,如果只是匹配,不论属性名称

awk -F= '$1 ~ /^myprop/ && $2 ~ /<br>/ { print $1 }' MyProject.properties