如何用awk或sed在Bash中把多行变量内容替换文件指定字符串?
如何用sed或awk将文件中的字符串替换为带换行的Bash变量值
我明白你遇到的问题了——你想把文件里的zxcv替换成包含换行的变量值,但之前试的sed命令都没成功,核心问题在于Bash变量里的\n是字面字符,没转成实际换行,而且sed对特殊字符和换行的处理需要额外注意。下面给你两种可行的方案:
方案一:用awk(更简单可靠)
awk处理包含换行的变量替换要省心很多,直接把shell变量传递给awk,然后用全局替换函数gsub就行:
首先先把变量里的\n转换成实际的换行符(这步很关键,不然替换的还是字面的\n):
VAR="This is \n what i want" VAR=$(echo -e "$VAR") # 把转义的\n变成真实换行
然后执行awk命令替换文件内容:
awk -v var="$VAR" '{gsub(/zxcv/, var)}1' filename > temp_file && mv temp_file filename
如果你的系统装的是GNU awk 4.1及以上版本,还可以直接原地替换,不用临时文件:
gawk -i inplace -v var="$VAR" '{gsub(/zxcv/, var)}1' filename
解释一下:-v var="$VAR"把shell的VAR变量传递给awk内部的var变量;gsub(/zxcv/, var)会把每行里所有的zxcv替换成var的内容;最后的1是awk的简写,意思是打印处理后的每一行。
方案二:用sed(需要转义处理)
如果一定要用sed,得先把变量里的特殊字符和换行转义成sed能识别的格式:
同样先把\n转成实际换行:
VAR="This is \n what i want" VAR=$(echo -e "$VAR")
然后对变量进行转义处理(转义sed里的特殊字符/和&,同时把实际换行转成sed的\n转义序列):
VAR_ESCAPED=$(printf '%s' "$VAR" | sed -e 's/[\/&]/\\&/g' -e 's/\n/\\n/g')
最后执行sed替换:
sed -i "s/zxcv/$VAR_ESCAPED/g" filename
为什么你之前的命令失败了?
给你逐个分析下:
sed -i 's/zxcv/'$VAR'/g' filename:单引号里的变量不会被shell展开,而且$VAR没加引号,空格会导致shell把参数拆碎,直接报错。sed -i "s/zxcv/$VAR/g" filename:双引号展开了变量,但VAR里的\n是字面字符,不是实际换行;如果变量里有/这类sed的分隔符,还会直接破坏命令结构。sed -i "s/zxcv/$(VAR)/g" filename:$(VAR)是尝试执行名为VAR的命令,但VAR是变量不是命令,肯定报错。sed -i "s/zxcv/$(($VAR))/g" filename:$(())是算术运算语法,VAR是字符串,会触发语法错误。sed -i "s/zxcv/echo -n $VAR/g" filename:echo -n $VAR没给$VAR加引号,shell会把\n当成普通字符,还会把空格拆分,替换的还是字面的This is \n what i want,不是换行的内容。
内容的提问来源于stack exchange,提问作者mmichal10
相关产品推荐
相关产品推荐

