Помощь по написанию сценариев Awk — проблема с логикой

StackOverflow https://stackoverflow.com/questions/159423

  •  03-07-2019
  •  | 
  •  

Вопрос

В настоящее время я пишу простой .sh-скрипт для анализа файла журнала Exim на предмет строк, соответствующих "o'".В настоящее время при просмотре файла output.txt в каждой строке печатается 0 (606 строк).Я предполагаю, что моя логика неверна, поскольку awk не выдает никаких ошибок.

Вот мой код (обновлен для проблем с конкатенацией и счетчиком).Редактировать:Я взял новый код из ответа dmckee, над которым сейчас работаю, вместо старого кода в пользу простоты.

awk '/o'\''/ {
         line = "> ";
         for(i = 20; i <= 33; i++) {
           line = line " " $i;
         }
         print line;
    }' /var/log/exim/main.log > output.txt

Есть идеи?

РЕДАКТИРОВАТЬ:Для ясности я ищу букву «o» в адресах электронной почты, потому что «» является недопустимым символом в адресах электронной почты (а в наших базах данных он появляется только с именами с префиксом «o»).

РЕДАКТИРОВАТЬ 2:Согласно запросу на комментарий, вот очищенный образец желаемого результата:

[xxx.xxx.xxx.xxx] kathleen.o'toole@domain.com <kathleen.o'toole@domain.com> routing defer (-51): retry time not reached

[xxx.xxx.xxx.xxx] julie.o'brien@domain.com <julie.o'brien@domain.com> routing defer (-51): retry time not reached

[xxx.xxx.xxx.xxx] james.o'dell@domain.com <james.o'dell@domain.com> routing defer (-51): retry time not reached

[xxx.xxx.xxx.xxx] daniel_o'leary@domain.com <aniel_o'leary@domain.com> routing defer (-51): retry time not reached

Причина, по которой я начинаю цикл с 20, заключается в том, что все, что находится до 20-го поля, представляет собой просто стандартную информацию журнала, которая не нужна для моих целей.Все, что мне нужно, это все, начиная от IP и выше для этого решения (сообщения для каждой ошибки 550 различны для каждого используемого почтового сервера.Составляю список распространенных)

Это было полезно?

Решение

Здесь нет реальной необходимости в grep.Позвольте awk выбрать за вас совпадающие строки (и исправить ошибку конкатенации согласно ΤΖΩΤΖΙΟΥ):

awk '/o'\''/ {
             line = "> ";
             for(i = 20; i <= 33; i++) {
               line = line " " $i;
             }
             print line;
        }' /var/log/exim/main.log > output.txt

Конечно, в конечном итоге вам понадобится какой-то странный побег, если вы сделаете это на промопе, как указано выше.В сценарии чище...


Редактировать:При первом проходе я пропустил проблему +=...

Также предполагается, что строка, которую вы указали выше, является частичной, поскольку в ней всего 13 полей (по умолчанию поля разделены пробелами).

Другие советы

+ означает числовое сложение в awk.Если вы хотите объединить, просто разместите константы и/или выражения, разделенные пробелами.

Итак, это

line += " " + $i

должен стать

line = line " " $i

РЕДАКТИРОВАТЬ: Если Файлы журнала exim (я больше люблю Postfix :) разделяются одним пробелом, не проще ли:

grep -F o\' /var/log/exim/main.log | cut -d\  -f20-33 >output.txt

?

«'» не является незаконным в местных частях.От RFC2821, раздел 4.1.2:

Local-part = Dot-string / Quoted-string

Dot-string = Atom *("." Atom)

Atom = 1*atext

2821 дополнительные ссылки RFC2822 для нелокально определенных элементов, поэтому:

atext           =       ALPHA / DIGIT / ; Any character except controls,
                        "!" / "#" /     ;  SP, and specials.
                        "$" / "%" /     ;  Used for atoms
                        "&" / "'" /
                        "*" / "+" /
                        "-" / "/" /
                        "=" / "?" /
                        "^" / "_" /
                        "`" / "{" /
                        "|" / "}" /
                        "~"

Другими словами, «'» — это совершенно допустимый символ без кавычек, который можно использовать в локальной части электронного письма.Теперь это может быть не законно на вашем сайте, но это не то, что ты сказал.

Извините, что не прямо по теме, но хотел поправить ваше утверждение.

Не задача, и еще проще:питон.

import fileinput
for line in fileinput.input():
    if "'" in line:
        fields = line.split(' ')
        print "> ", ' '.join( fields[20:34] )
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top