![使用 sed 将匹配项替换为多行字符串](https://linux22.com/image/44451/%E4%BD%BF%E7%94%A8%20sed%20%E5%B0%86%E5%8C%B9%E9%85%8D%E9%A1%B9%E6%9B%BF%E6%8D%A2%E4%B8%BA%E5%A4%9A%E8%A1%8C%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
可能的重复:
将多行字符串插入另一个字符串
我有一个名为foo.txt
包含:
富 酒吧 巴兹
我想将每次出现的 替换bar
为存储在变量中的多行字符串$bar
:
1 2 3
导致:
富 1 2 3 巴兹
我可以awk
使用以下方法来做到这一点:
回声“$栏”| awk '{ if(文件名==“-”) { 如果(我!=“”) { 我=我“\n” } 我=我$0 } 别的 { if($0 == "酒吧") { 打印我 } 别的 { 打印 } } }'
但是尝试在sed
使用中执行相同的操作sed 's/bar/'"$bar"'/' foobar.txt
会出现错误:
sed: 1: “s/bar/1 2 3/":替代模式内未转义的换行符
这个问题可以解决吗?
如果有使用其他标准工具更简单的方法来做到这一点,我也想知道。
答案1
在 中sed
,换行符必须在命令的右侧转义s
,因此您需要编写它:
sed 's/foo/1\
2\
3/g'
一些sed
实现还支持(非标准):
sed 's/foo/1\n2\n3/g'
如果$bar
要替换,您需要首先在每个换行符之前插入反斜杠。当您这样做时,您还应该在每个斜杠、反斜杠和与号字符之前插入一个反斜杠。
就像是:
bar_escaped=$(printf '%s\n' "$bar" | sed 's,[\/&],\\&,g;s/$/\\/')
bar_escaped=${bar_escaped%?}
sed "s/foo/$bar_escaped/g"
答案2
我所做的是创建一个sed
模式文件,然后sed
使用指定的文件进行调用,而不是在命令中指定模式,因为您无法在命令行上执行多行操作(即 \n 不合法)。例如
sed -f pattern_file.sed infile.txt
就我而言,我想找到读取的每一行alarm_if_fail: 1
并添加application: XYZ
到下一行。所以模式文件.sed看起来如下:
1,/^END/{
s/^alarm_if_fail: 1$/&\
application: XYZ/
}
如果输入文件.txt好像
Unix
Stackexchange
alarm_if_fail: 1
ABC
然后ed -f pattern_file.sed infile.txt
就会返回
Unix
Stackexchange
alarm_if_fail: 1
application: XYZ
ABC