如何使用AWK/Sed搜索并替换文件中的多行指定文本?
刚好我经常处理这类文本区块替换的需求,给你分享两种实用的方法——用awk和sed都能搞定,具体看你习惯哪种工具:
用awk实现
awk处理多行文本区块的逻辑更清晰,用状态机的思路就能精准定位并替换:
awk ' /Things-I-WANT:/ { print "Things-I-WANT:" print " name: \"Banana\"" print " count: 7" in_want = 1 next } in_want && /^[^ ]/ { in_want = 0 } !in_want ' your_file.txt > new_file.txt
逻辑解释:
- 当匹配到
Things-I-WANT:这一行时,直接输出我们预定义的新内容,同时设置一个标记in_want=1,跳过当前行的后续处理。 - 当处于
in_want标记状态时,只要碰到非缩进开头的行,就说明目标区块结束了,立刻关闭标记。 - 不在标记状态的所有行,都原封不动输出。
如果需要原地修改文件,GNU awk可以加上-i inplace参数,就不用重定向到新文件了。
用sed实现
sed用范围匹配来定位目标区块,代码更紧凑,适合喜欢简洁写法的场景:
'/Things-I-WANT:/,/^[^ ]/{ /Things-I-WANT:/c\Things-I-WANT:\ name: "Banana"\ count: 7 /^[^ ]/!d }' your_file.txt > new_file.txt
逻辑解释:
- 首先用
/Things-I-WANT:/,/^[^ ]/锁定处理范围:从包含Things-I-WANT:的行开始,到第一个非缩进行结束。 - 在这个范围内,用
c命令把原有的Things-I-WANT:行替换成我们的新内容。 - 最后用
/^[^ ]/!d删除范围内的所有旧行(原来的name、count行),只保留新内容和区块结束的行。
同样,GNU sed支持原地修改,加上-i参数即可。
注意事项:
如果你的文本中缩进用的是Tab键而不是空格,记得把正则里的空格替换成\t;要是区块结束的规则有特殊情况,可以调整/^[^ ]/这个正则来匹配你的实际场景。
内容的提问来源于stack exchange,提问作者kn9
相关产品推荐
相关产品推荐

