在Shell变量中替换含指定模式的行并保留换行符
解决Shell变量中Sed替换后换行符丢失的问题
这问题我之前踩过坑!其实sed本身是能完美保留换行符的,问题出在bash处理变量展开和命令输出的方式上——如果不用引号包裹,bash会把所有空白字符(包括换行、制表符)都替换成空格,导致你看到的结果不对。
正确的处理步骤
用Sed替换并保留换行赋值变量
要保留换行,赋值时必须用双引号把命令替换的结果括起来,同时传递输入给sed时也要用引号包裹原变量:var='a foo b bar c something' # 替换包含bar的行为1 bar,并保留换行存入var2 var2="$(sed 's/^.*bar$/1 bar/' <<< "$var")"这里的
<<< "$var"是把原变量的内容(包含换行)作为sed的输入,加引号确保内容不会被bash分词;外层的双引号则保证sed输出里的换行符被完整保留在var2中。正确输出变量查看结果
输出变量时同样要加双引号,否则bash还是会把换行转成空格:echo "$var2"执行后就能得到你想要的结果:
a foo 1 bar c something
额外的替代方法(用Awk)
如果你习惯用awk,也可以达到同样效果,逻辑更直观:
var2="$(awk '/bar/{print "1 bar"; next}1' <<< "$var")"
解释一下awk的逻辑:匹配到包含bar的行时,输出1 bar并跳过后续动作;1是awk的默认动作(打印当前行),用来输出不匹配的原行。
关键注意点总结
- 传递含换行的变量给命令时,必须用双引号包裹变量,避免内容被bash拆分成多个参数。
- 捕获命令输出到变量时,用双引号包裹命令替换表达式,保留输出中的换行和空白格式。
- 输出变量查看结果时,同样要用双引号包裹变量,才能正确显示原始格式。
内容的提问来源于stack exchange,提问作者Mihael
相关产品推荐
相关产品推荐

