[英]Replace line with multi-line file
尝试用多行文件替换一行。 我可以使用单行文件或多行字符串轻松做到这一点(请参见下文)。
#!/bin/bash
NEW_STRING="apple\nbanana\ncarrot"
sed -i "3s/.*/$(echo "${NEW_STRING}")/" tmp.txt
# Outputs...
# line 1
# line 2
# apple
# banana
# carrot
# line 4
# line 5
# ...
# etc
但是,当我将代码更改为使用多文件(例如replace.txt
,收到以下错误:
sed: -e expression #1, char 10: unterminated `s' command
broken_script.bash
#!/bin/bash
FILE=`cat replace.txt`
sed -i "3s/.*/$(echo "${FILE}")/" tmp.txt
replace.txt
++++
++++++++++++++++++++++++++++++++++++++++++++++
apple size=8, align=2, ..., etc.
banana size=64, align=8, ..., etc.
...
carrot size=92, align=4, ..., etc.
注broken_script.bash
如果我删除工作replace.txt
是一个单行(即只是++++
)。
有人看到我在做什么错吗? 为什么不能将多行文件作为替换文本(例如,单行文件或多行字符串)使用呢?
要将行替换为文件的内容,可以使用r
命令:
sed -e 3rreplace.txt -e 3d tmp.txt
如注释中所述, sed -e 3d -e 3rreplace.txt
不起作用,因为d
命令在读取下一行后立即返回程序顶部,并且从不执行r
命令。
首先:删除echo
部分。 您可以直接使用该变量。
回到实际问题:
不同之处在于您对换行符进行编码的方式。 在第一个命令中,您写\\n
表示换行符。 \\n
不会被'bash'解释,而是直接发送给sed
。 在第二个命令中,文件内容发送到sed
,包括文字换行符。 对于具有两行line1
和line2
的文件, sed
看到的命令是
3s/.*/line1
line2/
sed
无法处理此类多行命令。
非sed解决方案:
看起来,您只想用另一个文件的内容替换一个文件的第三行。 这可以用
cat <(head -n 2 file1) file2 <(tail -n +4 file1)
head -n2 file1
打印的前两行file1
。
tail -n +4 file 1
从第4行开始打印file1
所有行。
<(command)
称为进程替换 ,它模拟包含command
的输出的文件。
cat
连接三个“文件”。
sed
可以通过一些引用杂耍来做到这一点
$ seq 5 | sed -e '/3/{r replace.txt' -e 'd}'
1
2
++++
++++++++++++++++++++++++++++++++++++++++++++++
apple size=8, align=2, ..., etc.
banana size=64, align=8, ..., etc.
...
carrot size=92, align=4, ..., etc.
4
5
对于就地替换,您需要提供文件
$ sed -i -e '/3/{r replace.txt' -e 'd}' file
当然先测试或备份。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.