Bash:将多线模式替换为另一模式

时间:2014-10-23 14:04:35

标签: bash awk sed grep

星期六我有一个文件,其中包含以下段落:

### END: HEADER ###

### BEGIN: OPERATING SYSTEM ###

我希望将其替换为:

### END: HEADER ###

### BEGIN: SECURITY ###
Retrieve /Extra/Keys/Root.key
Set SecurityStatus=1
### END: SECURITY ###

### BEGIN: OPERATING SYSTEM ###

如何使用Bash工具执行此操作?我会使用awk,grep,sed或三者的组合吗?执行上述示例的代码是什么?

5 个答案:

答案 0 :(得分:1)

sed -i '/HEADER/r file2.txt' file1.txt

FILE1.TXT

### END: HEADER ###

### BEGIN: OPERATING SYSTEM ###

FILE2.TXT

### BEGIN: SECURITY ###
Retrieve /Extra/Keys/Root.key
Set SecurityStatus=1
### END: SECURITY ###

答案 1 :(得分:1)

$ awk -v add='
### BEGIN: SECURITY ###
Retrieve /Extra/Keys/Root.key
Set SecurityStatus=1
### END: SECURITY ###' '{print} /### END: HEADER ###/{print add}' file
### END: HEADER ###

### BEGIN: SECURITY ###
Retrieve /Extra/Keys/Root.key
Set SecurityStatus=1
### END: SECURITY ###

### BEGIN: OPERATING SYSTEM ###

答案 2 :(得分:0)

您可以在i中使用sed(插入):

sed -i~ -e '/### BEGIN: OPERATING SYSTEM ###/i### BEGIN: SECURITY ###\
Retrieve /Extra/Keys/Root.key\
Set SecurityStatus=1\
### END: Security ###\

' file

答案 3 :(得分:0)

根据您希望的严格程度,您可能必须为此格式实现解析器。这是一个比迄今为止发布的sed解决方案稍微严格一点的Awk版本 - 如果END: HEADER模式之后的第二行不是BEGIN: OPERATING SYSTEM,它将会挽救之间没有空。

awk '/^### END: HEADER ###$/ { i=2; print; next }
    i==2 { if ($0 ~ /^$/) i--; else i=0 }
    i==1 && /^### BEGIN: OPERATING SYSTEM ###$/ {
        print; print "### BEGIN: SECURITY ###"; 
        print "Retrieve /Extra/Keys/Root.key"
        print "Set SecurityStatus=1"
        print "### END: SECURITY ###"; print ""; i=0; next }
    1' file

这演示了如何在标准输出上生成所需的输出。一旦你确信它有效,你就可以把它包装成像

这样的东西
awk '...' file >.file.new && mv .file.new file

用编辑后的版本替换原始文件。

答案 4 :(得分:0)

这可能适合你(GNU sed):

sed '/^### END: HEADER ###$/!b;n;/^\s*$/!b;n;/^### BEGIN: OPERATING SYSTEM ###$/i\### BEGIN: SECURITY ###\nRetrieve /Extra/Keys/Root.key\nSet SecurityStatus=1\n### END: SECURITY ###\n' file

按指定读取并打印出3行,并在第3行之前插入所需的字符串。