如何使用awk / sed命令在文件中查找块并在特定位置插入字符串

时间:2014-07-01 05:00:47

标签: shell

我的要求是读取一个文件并在一个块[]中找到一个字符串,并插入一个新字符串,然后是上面搜索过的字符串。

例如,输入文件中的数据类似于

#starting of the file
[MAIN]    
.   
.   
.   
connection = TCPIP   
connection = HTTP   
connection = HTTPS   
.   
.   
.   

[TCPIP]   
name =  tcpip1   
port = 2222   
.   
.   
.   

[HTTP]   
name = http1   
port = 3333   
.    
.   
.

[HTTPS]   
name = https1   
port = 4444   
.   
.   
.   
#end of the file 

我的要求是 1)我需要在最后一次连接后在[MAIN]块中插入一个新连接(MQ) 2)我需要在[MQ]的文件末尾插入一个块并插入所有必需的细节

预期输出应为

#starting of the file   
[MAIN]   
.   
.   
.   
connection = TCPIP   
connection = HTTP   
connection = HTTPS   
connection = MQ   
.   
.   
.   

[TCPIP]   
name =  tcpip1   
port = 2222   
.   
.   
.   

[HTTP]   
name = http1   
port = 3333   
.    
.   
.   
[HTTPS]   
name = https1   
port = 4444   
.   
.   
.   
[MQ]   
name = mq1   
port = 5555   
.   
.   
.   
#end of the file   

我尝试使用awk和sed命令查找字符串的出现并插入新字符串。但是,我没有找到如何获得最后一次出现的字符串[连接] 你能告诉我怎样才能实现这个目标?感谢。

1 个答案:

答案 0 :(得分:0)

有几种方法可以解决这个问题。这是一种方式(带样本输出):

$ awk '/\[MAIN\]/ {n=1;print;next} n==1 && /\[/ {n=0;print "CONNECTION=MQ\n"} {print} END {print "[MQ]\nname=mq1"}' input 
[MAIN]    
.   
.   
.   
connection = TCPIP   
connection = HTTP   
connection = HTTPS   
.   
.   
.   

CONNECTION=MQ

[TCPIP]   
name =  tcpip1   
port = 2222   
.   
.   
.   

[HTTP]   
name = http1   
port = 3333   
.    
.   
.

[HTTPS]   
name = https1   
port = 4444   
.   
[MQ]
name=mq1

让我们依次查看每个awk语句:

  • /\[MAIN\]/ {n=1;print;next}

    这将检查MAIN块的开始。如果它开始,它将标志n设置为1,打印要输出的行,然后跳转以开始下一行。

  • n==1 && /\[/ {n=0;print "CONNECTION=MQ\n"}

    此语句在MAIN之后的第一个块的开头执行。它在下一个块开始之前打印行CONNECTION=MQ。它还将标志n重置为零,以便我们知道我们已离开MAIN块

  • {print}

    这只是将输入行回显到标准输出。

  • END {print "[MQ]\nname=mq1"}

    在文件末尾,打印出您想要的新块。

如何就地修改

awk不直接支持修改源文件。然而,同样的效果很容易实现:

mv -f input input.bak && awk '/^\[MAIN\]/ {n=1;print;next} n==1 && /^\[/ {n=0;print "CONNECTION=MQ\n"} {print} END {print "[MQ]\nname=mq1"}' input.bak >input

以上内容创建了原始文件的备份副本,然后用修改后的版本覆盖原始文件。