tags:

views:

113

answers:

2

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 what 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

A: 

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
ghostdog74
Thanks, this modification did the trick!
embedded
A: 

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
Dennis Williamson