как удалить строку из файла с помощью awk, отфильтрованного по какой-либо строке - PullRequest
0 голосов
/ 18 апреля 2010

У меня есть файл, разделенный пробелом. Мне нужно написать команду 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 голосов
/ 18 апреля 2010

Вы должны поместить сценарии awk в одинарные кавычки и использовать передачу переменных, чтобы получить переменные оболочки в сценарий 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
0 голосов
/ 18 апреля 2010

вам не нужно устанавливать FS в пробел, так как по умолчанию FS уже пробел. И вам не нужно использовать \. Используйте параметр -v для передачи переменных оболочки в 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...