patterns.txt
^[s]*set breakpoint.*if
^[s]*set breakpoint.*in
^[s]*set breakpoint.*skip
脚本.txt
set breakpoint 1 at main.c:5
set breakpoint 2 at main.c:6
set breakpoint 3 at main.c:7
set breakpoint 4 if
示例和意外结果
当我运行cat "${script.txt}" | grep -f patterns.txt
时,结果是:
set breakpoint 1 at main.c:5 // WHY DOES THIS MATCH???
set breakpoint 2 at main.c:6 // WHY DOES THIS MATCH???
set breakpoint 3 at main.c:7 // WHY DOES THIS MATCH???
set breakpoint 4 if
同样适用于:
cat "${script.txt}" | grep -E '^[s]*set breakpoint.*if|^[s]*set breakpoint.*in|^[s]*set breakpoint.*skip'
这是因为breakpoint.*in
在前 3 行中匹配breakpoint <digit> at main
(main
以 in
结尾)。
您应该在模式中使用结束锚点,如下所示:
cat patterns.txt
^s*set breakpoint.*if$
^ss*et breakpoint.*in$
^ss*et breakpoint.*skip$
否则:
^s*set breakpoint.*i[fn]$
^ss*et breakpoint.*skip$
贪婪的表达式
^[\s]*设置断点。
你的正则表达式太贪婪了。 .*
通常是问题所在,因为它会消耗尽可能多的内容,其中包括"main"中的"in"。你需要一个不那么贪婪的表达,以及一个更精确的模式。
使用单词边界
使表达式不那么贪婪的一种方法是让模式将单词边界与b
原子匹配。例如,在模式中的关键字之前添加单词边界.txt如下所示:
^[s]*set breakpoint.*bif
^[s]*set breakpoint.*bin
^[s]*set breakpoint.*bskip
然后,当您运行扩展的 grep 时,您将只获得您可能期望的输出:
$ egrep -f pattern.txt script.txt
set breakpoint 4 if