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


8

假设我在中有一段文字~/.bashrc

#~/.bashrc
# ...some commands...

# aliases
alias suicide='sudo rm -rf /'
# end aliases

# other commands

我希望将该文本块替换为另一个文件中两个标记之间包含的一些其他文本: stuff-to-place-in-bashrc.txt

# stuff-to-place-in-bashrc.txt
# ...stuff...

# aliases
alias ldir='ls * -d'
alias ithinklifeisworthliving='echo all good'
# end aliases

# ...more stuff...

我试过了

 sed -ne 's/# aliases\s+\(.*\)\s+# end aliases/\1/' stuff-to-place-in-bashrc.txt

但是我真的在黑暗中摇摆。有人可以帮我吗?

  1. 如何从中提取文本stuff-to-place-in-bashrc.txt

  2. 如何~/.bashrc用问题1中的提取文本替换另一部分?

编辑

谢谢你们的更新,那些想知道为什么我想要这样的人:

允许对脚本文件进行精心挑选的更新,而不会覆盖用户添加的内容。对于共享和经常更新的标准操作环境非常有用(例如我在Tyro的上一份工作是用XP编码的)。

去疯狂的家伙。


另请参见在C预处理文件中的花括号之间捕获文本。用您的开始和结束标记(# aliases# end aliases)更改“花括号” ,它可能对您有用。

Answers:


9

Ed是标准编辑器,因为您可以使用它来开发ed脚本并让它像以前测试过的那样以交互方式完成其工作。对于像这样的小文件.bashrc或任何代码文本,ed是有效的,因为ed可以一口气读取整个文件并使用缓冲区。出于同样的原因,您不应将ed用于日志文件之类的大文件。

但是使用ed脚本,您的工作很快就完成了:

ed ~/.bashrc<<EOF
/^# aliases
+,/^# end aliases/-1d
-r !sed -n '/^# aliases/,/^# end aliases/p' stuff-to-place-in-bashrc.txt|grep -v '^#'
w
q
EOF

我使用类似的脚本来自动调整配置文件,例如ALS .asoundrc,以适应将笔记本电脑带到的不同环境。

关于ed的最佳文档来自非常酷的PLAN9系统的简单手册页。我将其翻译为ed.ps文件。如果您对PLAN9感兴趣,则应检查9fronthttp://cat-v.org/,因为原始的bell labs版本仍在维护,但文件系统非常简单。

关于编辑器战争,emacs,vim等的最终结论:acme规则!


感谢您的回答,它已经奏效,但是我不确定语法是什么。它使用正则表达式还是更特定于ed的东西?好像有vim一样的命令(wq
thenaglecode 2015年

它使用正则表达式(/^# aliases/^# end aliases/),其他命令为Vi / Ed。请参阅例如vimhelp.appspot.com/cmdline.txt.html#%3Arange for +, /^# end aliases/
muru

1
看到info Ed你的系统(希望)上。我不知道为什么现代的Linux发行版没有安装这个很棒的编辑器。w和q是write和quit命令。ed的工作原理与regex的sed非常相似。名称听起来如此相似是有原因的。d表示删除前面的行,-r将后面!命令的结果读入前一行。我在编辑时缩短了文件名,因为今天清晨我懒得打字。
ikrabbe 2015年

1
@thenaglecode看到我的最后编辑。我必须先测试一下,然后再发布。
ikrabbe 2015年

1
@thenaglecode我需要的关于ed的唯一且唯一非常好的页面是plan9的ed(1)页面:man.cat-v.org/plan_9/1/ed如果您愿意,我可以给您发送一个脚本版本。当我们在谈论plan9时,也请参阅acme编辑器。如果您习惯了这一点,就永远不会使用其他东西。当然,最好是使用plan9系统,例如,将其用作Linux机器内的虚拟机,但是unix的p9p端口也很棒。(plan9 ed和gnu ed之间几乎没有区别!)
ikrabbe15年

2
set /^\#aliases/  /^\#end\ aliases/
sed -ne"$1,$2"'s/\\\{0,1\}/&&/gp' <stuff_to_place...rc |
sed -e"$1,$2c\" -f- ./infile >./outfile

如果你想编辑就地该文件ed是一个非常好的解决方案。如果要在插播中进行编辑,请使用sed。避免sed -i


0

当然,您可以ed单独完成此操作,无需其他工具:

ed -s stuff_to_place.txt<<\IN
1,/# aliases/d
/# end aliases/,$d
,d
.r /home/username/.bashrc
/# aliases/x
.t.
.,/# end aliases/-d
,p
q
IN

如果您对结果感到满意,请替换,pw /home/username/.bashrc,将更改写入~/.bashrc(注意r和一起使用的完整路径w.bashrc如果位于中,则可以简单地使用cwd)。
工作原理:首先d从中删除不需要的行stuff_to_place.txt。然后,我们用删除其余的(别名),d。现在,文本缓冲区为空,而剪切缓冲区包含所需的行。然后,我们将r的内容读.bashrc入文本缓冲区,将剪切缓冲区的内容(x)放置到该/# aliases/行之后,复制粘贴的最后一行(.t.),然后从复制的行中删除,直到但不包括/# end aliases/,最后是print或write变化和q特效。

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.