[英]How to append entry the end of a multi-line entry using any of stream editors like sed or awk
我正在尝试使用脚本在sudoers文件中特定Host_Alias字段的多行条目的末尾附加主机名。
当前的sudoers文件的条目类似于:
Host_Alias srv_linuxestate= \
host10,host12,host13,host1,host50,\
host16,host1,host2,host11,host15,host21,\
host3,host14
我所需的输出将类似于以下内容,其中添加了“,host25”
Host_Alias srv_linuxestate= \
host10,host12,host13,host1,host50,\
host16,host1,host2,host11,host15,host21,\
host3,host14,host25
在此段之前和之后有更多行。
主机的值可能会更改,并且不是固定的。 同样,可能还有更多的上述行,并且在不完整行的末尾使用“ \\”将其分开。
任何帮助/指针都将很好。
这是sed
版本:
/^Host_Alias/{ # whenever we match Host_Alias at line start
:
/\\$/{N;b} # if backslash, append next line and repeat
s/$/,host25/ # add the new host to end of line
}
如果您只需要将新主机添加到其中一个主机别名中,请调整第一个匹配项以适合。 在您的示例中,如果可能有制表符而不是空格,则应该为/^Host_Alias *srv_linuxestate=/
或/^Host_Alias[ \\t][ \\t]*srv_linuxestate=/
。
如果需要将其作为sed -i -e '/^Host_Alias[ \\t][ \\t]*srv_linuxestate=/{;:;/\\\\$/{N;b};s/$/,host25/;}' /etc/sudoers
变成sed -i -e '/^Host_Alias[ \\t][ \\t]*srv_linuxestate=/{;:;/\\\\$/{N;b};s/$/,host25/;}' /etc/sudoers
。
使用带有空记录分隔符的awk:
awk -v RS= '$1=="Host_Alias" {$0 = $0 ",host25"} 1' /etc/sudoers
Host_Alias srv_linuxestate= \
host10,host12,host13,host1,host50,\
host16,host1,host2,host11,host15,host21,\
host3,host14,host25
假设在Host_Alias
最后一行之后有一个空行,就像在常规sudoers
文件中一样。
sed用于单行上的简单替换,仅此而已。 在aws被发明的1970年代中期,所有做其他事情的奥秘sed构造都已过时,因此只需使用awk:
$ awk '/Host_Alias/{f=1} f && !/\\/{$0=$0",host25"; f=0} {print}' file
Host_Alias srv_linuxestate= \
host10,host12,host13,host1,host50,\
host16,host1,host2,host11,host15,host21,\
host3,host14,host25
上面的代码只是在找到包含Host_Alias
设置了一个标志,并且当设置了该标志并且当前行不包含\\
,将,host25
的末尾添加,host25
并清除该标志。
简单,清晰,可维护,高效,可移植,可扩展等,在各个方面都比同等的sed解决方案更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.