Bash Grep精确匹配不起作用

Bash Grep精确匹配不起作用,bash,shell,Bash,Shell,我有一个属性文件 myprop2=this is with <br/> myprop2=这是与 当我试图为 grep "^myprop.*=.`*<br>*`" MyProject.properties | xargs | cut -d '=' -f 1 grep“^myprop.*=。`**`“MyProject.properties”xargs | cut-d'='-f 1 为什么会找到myprop2 注意:我发现而不是(不带结束标记)右角括号后的*使其在比赛

我有一个属性文件

myprop2=this is with <br/>
myprop2=这是与
当我试图为

grep "^myprop.*=.`*<br>*`" MyProject.properties | xargs | cut -d '=' -f 1
grep“^myprop.*=。`*
*`“MyProject.properties”xargs | cut-d'='-f 1
为什么会找到myprop2


注意:我发现

而不是

(不带结束标记)

右角括号后的
*
使其在比赛中被安全忽略了0次或更多次。我想你的意思是
…>*

此外,使用“前瞻”可以消除一些管道

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

如果不使用xargs和cut,则会给出相同的结果。您的双引号字符串包含
*
*
(的一个实例),这意味着Bash将尝试作为命令执行
*
*
,该命令将因各种原因失败,并将表达式扩展到该命令生成的stdout输出

由于失败的命令不产生标准输出,
`…`
表达式扩展为空字符串,这意味着
grep
将看到以下字符串文本:
^myprop.*=。”

myprop
开头的任何行,最后后跟一个
=
和至少1个字符。与此正则表达式匹配,而不管后面是什么-这就是
myprop2
行匹配的原因

如果要将反勾号作为文本进行匹配,则可以将其转义为
\`
,或者使用单引号字符串代替。
(如果您认为
*
字符必须在带引号的字符串中转义才能按字面意思处理:它们不是-只有不带引号的用法才需要转义)

但是,正确地说,即使您没有将
*
*
括在反勾中,在
>
后面加上重复符号
*
意味着任何数量的
实例都不匹配

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

因此,虽然使用
*
而不是
*
跟随
可以解决该问题,但没有必要使用
结束正则表达式

因此,他的GNU
grep
解决方案(因为只有GNU
grep
支持
-p
选项以支持前瞻断言等功能)可以简化为:

grep -oP 'myprop.*(?==.*<br>)' MyProject.properties
或者,使用
awk

awk -F= '$1 ~ /^myprop/ && $2 ~ /<br>/ { print $1 }' MyProject.properties
awk-F='$1~/^myprop/&&$2~/
/{print$1}'MyProject.properties
或者,如果只是关于匹配值,则与属性名称无关:

awk-F='$2~/
/{print$1}'MyProject.properties
grep解决方案很有帮助,但是您应该提到它需要GNU
grep
。虽然
*
的解释原则上是正确的,但OP更直接的问题是在backticks中包含
*
*
。另外,虽然
.
而不是
*
确实有效,但值得指出只要
就行了,因为这行的其余部分不需要匹配。我只是喜欢你的答案…并感谢你为详细阐述所付出的努力。脱帽致敬!@Nearrouser:我感谢你的反馈;我很高兴你发现答案很有用。
awk -F= '$1 ~ /^myprop/ && $2 ~ /<br>/ { print $1 }' MyProject.properties
awk -F= '$2 ~ /<br>/ { print $1 }' MyProject.properties