假设有一段文字(汇编代码)
st.w av,d15
ld.w d15,av
假设我们想用 grep 来匹配它。我们可以使用这个模式:
pattern=\
'\s+st.w\s+av,.*'\
'\s+ld.w\s+.*,av'
注意:我们用来.*
匹配寄存器名称。将来这些寄存器名称可能会更改。
假设我们想对寄存器名称使用特殊的正则表达式。我们添加特殊@reg
关键字:
pattern=\
'\s+st.w\s+av,@reg'\
'\s+ld.w\s+@reg,av'
然后我们为 grep 模式添加一个前置函数,将所有特殊关键字替换为实际的正则表达式模式:
preprocess_pattern () {
local result=$1
# Replace @reg to exact regex pattern [a..d][0..15].
result=${result//'@reg'/'[a-d](1[0-5]|[0-9])'}
# Add other replacements (if need).
#result=${result//''/''}
echo "$result"
}
然后我们preprocess_pattern()
在执行之前调用grep
:
pattern="$(preprocess_pattern $pattern)"
if ! grep -Pzo $pattern code.asm > /dev/null
then
echo "grep #$i failed (pattern: "$pattern")"
((++failed))
fi
它有效,但我们想要更多。
我们要添加@preg
,即以前的寄存器。
pattern=\
'\s+st.w\s+av,@reg'\
'\s+ld.w\s+@preg,av'
现在的问题是:在哪里(以及如何)添加逻辑,在每次出现之后@reg
节省d15
特殊堆栈/缓冲区中以及每次出现后的匹配值(在我们的例子中)@preg
检索@preg
来自堆栈/缓冲区的匹配值,并根据?的值检查该值
换句话说:如何编写模式来匹配数据上下文相关元素? grep 可以吗?
如果是(即可能)那么如何描述这一点上下文敏感性在模式中?
如果没有(即不可能)那么还有什么办法解决这个挑战呢?
答案1
您想要实现的目标可能可以通过 grep + 正则表达式来实现,但这会很复杂。您的任务需要完整的脚本或某种语言的程序。
遵循不同命令的特点可能会有所帮助
- Grep 上下文:grep 提供的唯一上下文是行数
before
和after
匹配行 [-A
,-B
,-C
(前两者的组合)] - Awk 和 Sed :使用它们您可以搜索 2 种模式内的文本。
但同样,这会变得很复杂。据我了解,您正在尝试编写某种解析器,因此您应该在开始编写复杂命令之前研究并尝试使用编写工具。