I have a file delimited by space. I need to write an awk command that receives a host name argument and it should replace the host name if it already defined in the file. It must be a full match not partially - if the file contains this host name: localhost searching for "ho" will fail and it will be added to the end of the file.
another option is a delete: again awk receives host name argument and it should remove it from the file if exists.
This is w开发者_开发知识库hat I have so far: (It needs some enhancements)
if [ "$DELETE_FLAG" == "" ]; then
# In this case the entry should be added or updated
# if clause deals with updating an existing entry
# END clause deals with adding a new entry
awk -F"[ ]" "BEGIN { found = 0;} \
{ \
if ($2 == $HOST_NAME) { \
print \"$IP_ADDRESS $HOST_NAME\"; \
found = 1; \
} else { \
print \$0; \
} \
} \
END { \
if (found == 0) { \
print \"$IP_ADDRESS $HOST_NAME\";
} \
} " \
/etc/hosts > /etc/temp_hosts
else
# Delete an existing entry
awk -F'[ ]' '{if($2 != $HOST_NAME) { print $0} }' /etc/hosts > /etc/temp_hosts
fi
Thanks
you don't have to set FS
to space, since by default FS
is already spaces. And you don't have to use \
. Use the -v
option to pass in shell variables to awk. And there is no need to use semi-colon at end of every statement
if [ "$DELETE_FLAG" == "" ]; then
# In this case the entry should be added or updated
# if clause deals with updating an existing entry
# END clause deals with adding a new entry
awk -v hostname="$HOST_NAME" -v ip="$IP_ADDRESS" 'BEGIN { found = 0}
{
if ($2 == hostname) {
print ip" "hostname
found = 1
} else {
print $0
}
}
END {
if (found == 0) {
print ip" "hostname
}
}' /etc/hosts > /etc/temp_hosts
else
# Delete an existing entry
awk -v hostname="$HOST_NAME" '$2!=hostname' /etc/hosts > /etc/temp_hosts
fi
You should put the awk scripts inside single quotes and use variable passing to get the shell variables into the awk script. Then you won't have to do all that escaping. And I don't think the line-continuation backslashes and semicolons are necessary.
Are the field separators spaces or are they spaces inside square brackets?
awk -F ' ' -v awkvar=$shellvar '
BEGIN {
do_something
}
{
do_something_with awkvar
}' file > out_file
Also, there's a slight danger that your tests will fail if the variable contains a string starting with a dash. There are at least a couple of ways to protect against this:
if [ "" == "$DELETE_FLAG" ]; then # the dash isn't the first thing that `test` sees
if [ x"$DELETE_FLAG" == x"" ]; then # ditto
精彩评论