BASH。解析具有附加条件的文本块

时间:2015-12-18 14:46:08

标签: bash awk sed

我有一项任务是将nagios从版本2升级到4.有几百个文件已弃用标签。这是其中之一:

define host {
        use h-common1
        host_name a0
        address XX.XX.XX.XX
        check_command check-host-alive
        parents fw_ext
        }
define hostextinfo {
        host_name a0
        icon_image serv.jpg
        statusmap_image serv.jpg
       }
define service {
        use s-common1
        host_name a0
        service_description check_load
        check_command check_nrpe! check_load
        }

define service {
        use s-common1
        host_name a0
        service_description check-disks
        check_command check_nrpe! check_disk
        }
define service {
        use s-common1
        host_name a0
        service_description check_crond
        check_command check_nrpe! check_procs
        }
define service {
        use s-common1
        host_name a0
        service_description check_ntpd
        check_command check_nrpe! check_procs_1
        }
define service {
        use s-common1
        host_name a0
        max_check_attempts 1
        notification_options c, w
        service_description Find errors in logs
        check_command check_nrpe! check_logct
        }

如何删除标记为“host_name”的所有行,但“块主机”块中的行除外? 例如,我使用这种结构删除所有块“define hostextinfo”:

for i in * ; do cat $i | sed -e '/}/r exceptions' -e '/^define hostextinfo{/,/}/d' > $i.tmp ; cat $i.tmp > $i; rm $i.tmp ;done

如何根据我的情况修改此代码?如果我在一行中找到解决方案,我会很高兴。

3 个答案:

答案 0 :(得分:4)

试试这行:

awk '/^define host /{k=1}/[}]/{k=0}!k&&/host_name/{next}7' file

答案 1 :(得分:1)

sed用于单个行上的简单替换,即全部。除了s,g和p(带-n)之外的所有结构在20世纪70年代中期被发明时已经过时,人们只是在今天使用它们进行心理练习,而不是实际创建他们将使用的脚本。

你没有发布预期的输出,所以我们都在猜测,但这是你想要的吗?

$ awk '$1=="define"{type=$2} !($1=="host_name" && type!="host")' file
define host {
        use h-common1
        host_name a0
        address XX.XX.XX.XX
        check_command check-host-alive
        parents fw_ext
        }
define hostextinfo {
        icon_image serv.jpg
        statusmap_image serv.jpg
       }
define service {
        use s-common1
        service_description check_load
        check_command check_nrpe! check_load
        }

define service {
        use s-common1
        service_description check-disks
        check_command check_nrpe! check_disk
        }
define service {
        use s-common1
        service_description check_crond
        check_command check_nrpe! check_procs
        }
define service {
        use s-common1
        service_description check_ntpd
        check_command check_nrpe! check_procs_1
        }
define service {
        use s-common1
        max_check_attempts 1
        notification_options c, w
        service_description Find errors in logs
        check_command check_nrpe! check_logct
        }

通常情况下,我建议不要采取双重否定,但在这种情况下,如果你删除双重否定,我会发现上述内容比其他更容易理解:

awk '$1=="define"{type=$2} $1!="host_name" || type=="host"' file

答案 2 :(得分:0)

另一个awk

 awk '             /define/{del=1}  
       /define host/ || /}/{del=0} 
        /host_name/ && del {next} 1' recs