我有文件“acl.txt”
192.168.0.1 192.168.4.5 #start_exceptions 192.168.3.34 192.168.6.78 #end_exceptions 192.168.5.55
和另一个文件“例外”
192.168.88.88 192.168.76.6
我需要将#start_exceptions和#end_exceptions之间的所有内容replace为exception文件的内容。 我已经尝试了这个论坛的许多解决scheme,但没有一个是可行的。
编辑 :
好的,如果你想保留#start和#stop,我将恢复到awk:
awk ' BEGIN {p=1} /^#start/ {print;system("cat exceptions");p=0} /^#end/ {p=1} p' acl.txt
感谢@fedorqui在下面的评论调整。
输出:
192.168.0.1 192.168.4.5 #start_exceptions 192.168.88.88 192.168.76.6 #end_exceptions 192.168.5.55
p是表示是否打印行的标志。 它从头开始为1,因此所有行都被打印,直到找到以#开始的行。 然后,我捕捉异常文件的内容并停止打印行,直到找到以#end开头的行,此时我将p标志设置回1,以便打印剩余的行。
如果你想输出到一个文件,像这样在命令的最后加上“> newfile”:
awk ' BEGIN {p=1} /^#start/ {print;system("cat exceptions");p=0} /^#end/ {p=1} p' acl.txt > newfile
如果您真的想要使用SED,还有其他版本
如果你确实想要用sed来做,你可以使用嵌套的地址空间,首先选择#start_exceptions和#end_exceptions之间的行,然后再选择第一行,也是除了#end_exceptions之外的行:
sed ' /^#start/,/^#end/{ /^#start/{ n r exceptions } /^#end/!d } ' acl.txt
输出:
192.168.0.1 192.168.4.5 #start_exceptions 192.168.88.88 192.168.76.6 #end_exceptions 192.168.5.55
原来的答案
我认为这将工作:
sed -e '/^#end/r exceptions' -e '/^#start/,/^#end/d' acl.txt
当它发现/ ^#end /它读入例外文件。 它还会删除/#start /和/#end /之间的所有内容。
为了表达技术的清晰性,我留下了略微“松散”的匹配。
您可以使用以下内容,基于将字符串替换为使用sed的文件内容 :
$ sed $'/end/ {r exceptions\n} ; /start/,/end/ {d}' acl.txt 192.168.0.1 192.168.4.5 192.168.88.88 192.168.76.6 192.168.5.55
sed $'one_thing; another_thing' ac1.txt
sed $'one_thing; another_thing' ac1.txt
执行这两个操作。 /end/ {r exceptions\n}
如果该行包含end
,则读取文件exceptions
并将其追加。 /start/,/end/ {d}
从包含start
的行到包含end
的行,删除所有行。 我在MINGW的Mark Setchell解决方案中遇到了问题。 脱字符号不是开始行。 事实上,分离器的检测是依赖于它是在行的开始? 我想出了这个awk的替代方案
$ awk -v data="$(<exceptions)" ' BEGIN {p=1} /#start_exceptions/ {print; print data;p=0} /#end_exceptions/ {p=1} p ' acl.txt