sed命令仅在第一实例执行时执行

时间:2019-02-19 21:16:00

标签: sed

我正在搜索特定的字符串,并在其后添加一系列行。我现在使用的sed命令是:

sed -i "
/CLIENTVERSION/ {
n
a\define service{
a\        use                     generic-service
a\        host_name               $var_hostname
a\        service_description     NSCLient++ Version
a\        check_command           check_nt!CLIENTVERSION
a\        }
}" windows.cfg;

windows.cfg文件包含特定主机的服务定义。 (SBS和Test1主机已经在文件中,并且Test2是运行我的命令后的输出。我的输出是:

define service{
    use                     generic-service
    host_name               sbs
    service_description     NSClient++ Version
    check_command           check_nt!CLIENTVERSION
    }
define service{
    use                     generic-service
    host_name               Test2
    service_description     NSCLient++ Version
    check_command           check_nt!CLIENTVERSION
    }
 define service{
    use                     generic-service
    host_name               Test
    service_description     NSCLient++ Version
    check_command           check_nt!CLIENTVERSION
    }
define service{
    use                     generic-service
    host_name               Test2
    service_description     NSCLient++ Version
    check_command           check_nt!CLIENTVERSION
    }

我想要:

define service{
    use                     generic-service
    host_name               sbs
    service_description     NSClient++ Version
    check_command           check_nt!CLIENTVERSION
    }
define service{
    use                     generic-service
    host_name               Test2
    service_description     NSCLient++ Version
    check_command           check_nt!CLIENTVERSION
    }
define service{
    use                     generic-service
    host_name               Test
    service_description     NSCLient++ Version
    check_command           check_nt!CLIENTVERSION
    }

我认为/ g选项可以做到这一点,但是我还没有建立它,并且不确定为什么它要两次添加“ Test2”服务定义。

2 个答案:

答案 0 :(得分:1)

您可能会发现awk更易于使用。对gensub()和多字符RS使用GNU awk:

$ cat tst.sh
#!/bin/env bash
infile="$1"

var_hostname="Test2"

awk -v RS='^$' -v ORS= '
NR==FNR { rec=$0; next }
{ print gensub(/CLIENTVERSION\n[^\n]+\n/,"&"rec,1) }
' - "$infile" <<!
define service{
    use                     generic-service
    host_name               $var_hostname
    service_description     NSCLient++ Version
    check_command           check_nt!CLIENTVERSION
    }
!

$ ./tst.sh file
define service{
    use                     generic-service
    host_name               sbs
    service_description     NSClient++ Version
    check_command           check_nt!CLIENTVERSION
    }
define service{
    use                     generic-service
    host_name               Test2
    service_description     NSCLient++ Version
    check_command           check_nt!CLIENTVERSION
    }
define service{
    use                     generic-service
    host_name               Test
    service_description     NSCLient++ Version
    check_command           check_nt!CLIENTVERSION
    }

只要愿意,只需将awk更改为awk -i inplace进行就地编辑(例如sed -i)即可。以上是在此输入文件上运行的:

$ cat file
define service{
    use                     generic-service
    host_name               sbs
    service_description     NSClient++ Version
    check_command           check_nt!CLIENTVERSION
    }
define service{
    use                     generic-service
    host_name               Test
    service_description     NSCLient++ Version
    check_command           check_nt!CLIENTVERSION
    }

答案 1 :(得分:0)

this answer借用的方法在这里起作用:

sed -i "
/CLIENTVERSION/ {
n
a\define service{
a\        use                     generic-service
a\        host_name               $var_hostname
a\        service_description     NSCLient++ Version
a\        }
:a;n;ba}" windows.cfg

区别在于脚本的最后一行,这使它进入循环,该循环无需任何处理即可静默读取文件的其余部分。