当前位置: 动力学知识库 > 问答 > 编程问答 >

linux - How to append entry the end of a multi-line entry using any of stream editors like sed or awk

问题描述:

I am trying to use a script to append the host name at the end of a multi-line entry of a specific Host_Alias field in sudoers file.

The current sudoers file has an entry similar to :

Host_Alias srv_linuxestate= \

host10,host12,host13,host1,host50,\

host16,host1,host2,host11,host15,host21,\

host3,host14

My required output would be something like the following where I have added ",host25"

Host_Alias srv_linuxestate= \

host10,host12,host13,host1,host50,\

host16,host1,host2,host11,host15,host21,\

host3,host14,host25

There are more lines before and after this segment.

The values for the hosts could change and is not fixed. Also there could be many more lines as above and these being separated using "\" at the end of the incomplete line.

Any help/pointers would be great.

网友答案:

Here's a sed version:

/^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
}

If you need to add your new host to just one of the host aliases, adjust the first match to suit. In your example, it should probably be /^Host_Alias *srv_linuxestate=/, or /^Host_Alias[ \t][ \t]*srv_linuxestate=/ if there might be tabs instead of spaces.

If you need it as a one-liner, that becomes sed -i -e '/^Host_Alias[ \t][ \t]*srv_linuxestate=/{;:;/\\$/{N;b};s/$/,host25/;}' /etc/sudoers.

网友答案:

Using awk with empty record separator:

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

This is assuming there is an empty line after last line of Host_Alias as in the regular sudoers file.

网友答案:

sed is for simple substitutions on single lines, that is all. All of the arcane sed constructs to do anything else became obsolete in the mid-1970s when awk was invented so just use 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

The above simply sets a flag when it finds a line containing Host_Alias and when that flag is set and the current line doesn't contain \ it adds ,host25 to the end of the line and clears the flag.

Simple, clear, maintainable, efficient, portable, extensible, etc. etc. - better in every way than an equivalent sed solution.

分享给朋友:
您可能感兴趣的文章:
随机阅读: