如何修改sed命令,仅匹配指定模式时替换,避免无匹配时追加内容?
问题
我有一个包含两行内容的文件:
A[0x000]: 0x00120001 0x00000000 0x00000000 0x00000000 A[0x000]: 0x12341234 0x11110987 0x34567890 0x45789756
当前使用的sed命令:
sed -E -i 's|(A\[0x000\]:\s+0x)[0-9]+|\1xx0000x|g' filename
执行后第一行替换正常,但第二行出现错误追加,结果如下:
A[0x000]: 0x00xx000x 0x00000000 0x00000000 0x00000000 A[0x000]: 0x00xx000x12341234 0x11110987 0x34567890 0x45789756
需要修改命令,实现仅匹配指定模式时替换,得到预期结果:
A[0x000]: 0x00xx000x 0x00000000 0x00000000 0x00000000 A[0x000]: 0x12341234 0x11110987 0x34567890 0x45789756
解决方案
原命令的问题在于正则匹配范围过宽:[0-9]+会匹配任意长度的数字序列,加上g全局替换标志,导致第二行不符合要求的内容也被错误匹配。以下是两种修正方案:
方案1:精准匹配目标数字串
直接锁定要替换的完整数字串,确保仅第一行触发替换:
sed -E -i 's|(A\[0x000\]:\s+)0x00120001|\10x00xx000x|' filename
- 移除
g标志,避免一行内多次替换 - 精准匹配
0x00120001,只有第一行会满足替换条件
方案2:匹配前缀特征(适配同类格式)
如果需要替换所有以0x00开头的8位数字,可通过限定长度的正则实现:
sed -E -i 's|(A\[0x000\]:\s+0x00)[0-9]{2}([0-9]{2})[0-9]{2}|\1xx\20x|' filename
- 捕获组
\1保留A[0x000]: 0x00前缀 - 将中间两位数字替换为
xx,最后两位替换为0x,刚好得到目标格式0x00xx000x - 第二行数字以
0x12开头,不匹配0x00前缀,因此不会被修改
原命令出错原因
原命令中[0-9]+仅匹配任意长度的数字,在第二行中会错误匹配0x后的部分数字(比如前两位12),替换后剩余的341234被保留,最终出现0x00xx000x12341234的错误结果;g全局标志还可能触发多次替换,进一步放大问题。
内容的提问来源于stack exchange,提问作者vidya
相关产品推荐
相关产品推荐

