使用fmt后sed变量替换失效的解决办法求助
解决sed替换时因fmt换行符导致的命令失效问题
你猜的完全没错!问题就出在fmt给变量$var插入的换行符上。sed的s/查找/替换/命令里,替换文本中的换行符会被sed当成命令的结束标记——它读到换行就以为你的s命令没写完,所以才会抛出unterminated 's' command的错误。
下面给你两种可行的解决思路,既能保留fmt每行80字符的格式化效果,又能让替换正常工作:
方法一:处理变量换行符为sed可识别的转义序列
我们可以把fmt生成的换行符替换成sed能解析的\n转义字符,同时去掉原始的换行,让sed能正确解析替换内容:
# 先格式化变量,并把换行转成sed可识别的\n var=$(echo "$var" | fmt | sed 's/$/\\n/g' | tr -d '\n') # 执行sed替换 echo "This is a sample string which is of multiline" | sed -r "/sample/ {n;s/^/ $var /g}"
这里的关键细节:
echo "$var"一定要加引号,不然shell会把变量里的连续空格合并,直接影响fmt的格式化效果sed 's/$/\\n/g'给每一行末尾加上转义后的换行符\n(两个反斜杠是为了让shell正确传递一个反斜杠给sed)tr -d '\n'去掉fmt生成的原始换行,把所有内容合并成一行,避免sed把换行误判为命令结束
方法二:用awk替代sed(更简洁直观)
awk对多行变量的支持比sed友好得多,我们可以直接把格式化后的变量传递给awk,逻辑也更清晰:
# 先格式化变量,保留原始换行 var_fmt=$(echo "$var" | fmt) # 用awk实现替换逻辑 echo "This is a sample string which is of multiline" | awk -v var="$var_fmt" '/sample/{print; print " " var; next}1'
解释一下awk的逻辑:
-v var="$var_fmt"把格式化后的变量传递给awk内部的var变量/sample/{print; print " " var; next}:当匹配到包含sample的行时,先打印当前行,再打印带前置空格的变量内容,然后next跳过后续处理1是awk的简写语法,代表打印所有未被上面逻辑处理的行(也就是原字符串的最后一行)
另外提醒一下:之前你写var=$(echo $var|fmt)的时候,echo $var没有加引号,这会导致shell把变量里的连续空格、换行都替换成单个空格,fmt的格式化效果会大打折扣,以后处理带空格/换行的变量时,一定要用双引号包裹变量。
内容的提问来源于stack exchange,提问作者monk
相关产品推荐
相关产品推荐

