如何使用由某些字符串过滤的awk从文件中删除一行

时间:2010-04-18 15:36:21

标签: linux shell awk

我有一个以空格分隔的文件。 我需要编写一个接收主机名参数的awk命令 它应该替换主机名,如果它已在文件中定义。 它必须是完全匹配而不是部分匹配 - 如果文件包含此主机名:localhost 搜索“ho”将失败,它将被添加到文件的末尾。

另一个选项是删除:再次awk接收主机名参数,如果存在,它应该从文件中删除它。

这是我到目前为止:(需要一些改进)

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

由于

2 个答案:

答案 0 :(得分:0)

您不必将FS设置为空格,因为默认情况下FS已经是空格。而且您不必使用\。使用-v选项将shell变量传递给awk。并且在每个陈述的末尾都不需要使用分号

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

答案 1 :(得分:0)

您应该将awk脚本放在单引号中并使用变量传递将shell变量放入awk脚本中。然后你不必做所有逃避。我不认为线条延续反斜杠和分号是必要的。

字段分隔符是空格还是方括号内的空格?

awk -F ' ' -v awkvar=$shellvar '
    BEGIN {
        do_something
    }
    {
        do_something_with awkvar
    }' file > out_file

此外,如果变量包含以短划线开头的字符串,则测试将会失败。至少有几种方法可以防止这种情况发生:

if [ "" == "$DELETE_FLAG" ]; then    # the dash isn't the first thing that `test` sees
if [ x"$DELETE_FLAG" == x"" ]; then  # ditto