sed命令仅在第一个实例上执行

sed命令仅在第一个实例上执行,sed,Sed,我正在搜索一个特定的字符串,并在其后追加一系列行。我现在拥有的sed命令是: sed -i " /CLIENTVERSION/ { n a\define service{ a\ use generic-service a\ host_name $var_hostname a\ service_description NSCLient++ Version a\ che

我正在搜索一个特定的字符串,并在其后追加一系列行。我现在拥有的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”服务定义。

您可能会发现awk更容易使用。使用GNU awk for gensub()和multi char RS:

$ 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
    }
!
如果愿意,只需将
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
    }

这里借用了works的方法:

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

不同之处在于脚本的最后一行,它将脚本放入一个循环中,该循环无需任何处理就可以静默地读取文件的其余部分。

请检查
/g
的意思是
对整行中的每一个匹配项重复执行
。这与整个文件中的匹配项无关-整个文件中的每一行匹配项都是无效的就像sed默认做的那样。
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