尝试用多行文件替换行。我可以使用单行文件或多行字符串轻松完成此操作(见下文)。
#!/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
),请注意++++
。
有谁看到我做错了什么?为什么这不能用多行文件作为替换文本(例如单行文件或多行字符串)?
答案 0 :(得分:2)
要用文件内容替换行,可以使用r
命令:
sed -e 3rreplace.txt -e 3d tmp.txt
正如评论中所述,sed -e 3d -e 3rreplace.txt
不起作用,因为d
命令在读取下一行后立即返回到程序的顶部,并且从不执行r
命令。
答案 1 :(得分:1)
首先:放弃echo
部分。您可以直接使用该变量。
回到实际问题:
区别在于您如何编码换行符。在您编写\n
的第一个命令中,确实表示换行符。 \n
不会被' bash'解释,而是直接发送到sed
。在第二个命令中,文件内容将发送到sed
,包括文字换行符。对于包含line1
和line2
两行的文件,sed
看到的命令是
3s/.*/line1
line2/
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
连接三个&#34;文件&#34;。
答案 2 :(得分:1)
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
当然先测试或备份。