繁体   English   中英

用多行文件替换行

[英]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 ,包括文字换行符。 对于具有两行line1line2的文件, 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM