如何用Bash命令替换文件中两个标签间的多行文本?
多行标签间文本替换解决方案
你之前的sed命令失效,核心原因是sed默认按单行处理,.*仅能匹配当前行内字符,无法覆盖跨换行的标签间内容,所以没法完成多行替换。以下是几种跨平台可行的实现方式:
一、sed实现(分Linux/macOS)
macOS(BSD sed)
保留标签,替换中间内容
sed -i '' '/^#STARTTAG$/,/^#ENDTAG$/{/^#STARTTAG$/!{/^#ENDTAG$/!d;}; s/#ENDTAG$/new content line 1\nnew content line 2/;}' somefile
逻辑:定位标签行范围,删除中间所有行,再将结束标签替换为你的多行内容。
连标签一起替换
sed -i '' -e '/^#STARTTAG$/,/^#ENDTAG$/c\ new content line 1\ new content line 2\ new content line 3' somefile
注意:c\后每一行内容末尾要加反斜杠(最后一行除外)。
Linux(GNU sed)
连标签一起替换(简洁版)
sed -i '/^#STARTTAG$/,/^#ENDTAG$/c new line 1\nnew line 2\nnew line 3' somefile
保留标签替换中间内容
sed -i '/^#STARTTAG$/{n;:a;N;/#ENDTAG$/!ba;s/.*\n/#STARTTAG\nnew content\n#ENDTAG/}' somefile
二、awk实现(跨平台一致)
awk处理多行逻辑更清晰,无需区分平台:
保留标签,替换中间内容
awk ' /^#STARTTAG$/ { print $0; print "new line 1"; print "new line 2"; skip=1; next; } /^#ENDTAG$/ { skip=0; next; } !skip { print $0; }' somefile > temp && mv temp somefile
连标签一起替换
awk ' /^#STARTTAG$/ { print "new line 1"; print "new line 2"; skip=1; next; } /^#ENDTAG$/ { skip=0; next; } !skip { print $0; }' somefile > temp && mv temp somefile
三、perl实现(最灵活)
perl支持一次性读取整个文件,完美处理多行匹配:
perl -i -0pe 's/^#STARTTAG\n.*?\n#ENDTAG$/new line 1\nnew line 2\nnew line 3/ms' somefile
参数说明:
-0:一次性读取整个文件-ms:m让^/$匹配行首行尾,s让.匹配换行符.*?:非贪婪匹配,避免误匹配多个标签块
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

