如何用另一个文本文件替换标记之间的文本文件的一部分?


26

说我有一个像这样的文本文件:

# custom content section
a
b

### BEGIN GENERATED CONTENT
c
d
### END GENERATED CONTENT

我想GENERATED CONTENT用另一个文件的内容替换标签之间的部分。

最简单的方法是什么?

Answers:


36
lead='^### BEGIN GENERATED CONTENT$'
tail='^### END GENERATED CONTENT$'
sed -e "/$lead/,/$tail/{ /$lead/{p; r insert_file
        }; /$tail/p; d }"  existing_file

优秀。sed不仅可以做更多的事情s/.../...
DevSolar 2012年

嗯,对我不起作用,我应该将sed命令放在一行上吗?
lzap 2014年

3
r insert_file命令必须是最后一行。请注意,空格和注释都不允许在其后。该代码已sed--posix启用了该选项的情况下使用GNU 进行了测试,并且按预期工作,因此它应可与所有posix兼容 sed
Peter.O 2014年

1
天哪,太酷了!这正在我的sed词典中!非常有用,非常简单。谢谢!
DanielSmedegaardBuus

2
请注意,就地编辑要求您捕获sed的输出(例如output=$(sed -e "..." existing_file)),然后在第二遍操作(例如echo "$output" > existing_file)中执行替换,因为尝试重定向到正在读取的文件将导致它在读取内容之前被截断。
克里斯·汤金森

5
newContent=`cat new_file`
perl -0777 -i -pe "s/(### BEGIN GENERATED CONTENT\\n).*(\\n### END GENERATED CONTENT)/\$1$newContent\$2/s" existing_file

不错的工作。比我的简单得多。:)
Kitty博士2012年

4

警告:这绝对不是最简单的方法。(编辑:bash起作用; POSIX grep也很好)

如果主要文本在文件“ main”中,而生成的内容在文件“ gen”中,则可以执行以下操作:

#!/bin/bash
BEGIN_GEN=$(cat main | grep -n '### BEGIN GENERATED CONTENT' | sed 's/\(.*\):.*/\1/g')
END_GEN=$(cat main | grep -n '### END GENERATED CONTENT' | sed 's/\(.*\):.*/\1/g')
cat <(head -n $(expr $BEGIN_GEN - 1) main) gen <(tail -n +$(expr $END_GEN + 1) main) >temp
mv temp main

这样行吗?我认为您的最后一行将main在cat读取之前打开以供编写和清除。
chepner 2012年

@chepner废话,你是对的。其余的工作,但是。我会解决的。
Kitty博士2012年

3
ed -s FILE1 <<EOF
/### BEGIN GENERATED/+,/### END GENERATED/-d
/### BEGIN GENERATED/ r FILE2
w
q
EOF

使用heredoc和ed行编辑器。Heredoc中的第一行将删除'+'之后的'd'行,'###开始生成...',第二行的'-'之前的行将删除'd'。是在行### END GENERATED ...之后插入FILE2 ...
Jetchisel 2014年

对不起,我的意思是插入FILE2行“### BEGIN GENERATED ..”后
Jetchisel

放心吧,我毕竟是第一次:-)。另外,我可能使用了相同的词,但其他解决方案不使用heredocs,而是使用printf和管道。如果我犯了一个错误,请以任何方式道歉:-)
Jetchisel 2014年

谢谢,非常可读!顺便r FILE2说一句-代替您可以说r !command要从其他脚本中读取内容。
科斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.