Как снять срез?

8

Я хочу получить только адреса электронной почты, которые заканчиваются на "@ xyz.nl" из моего почтового журнала. Для этого я делаю:

# tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | cut -d '@' -f 1 | cut -d '<' -f 2

--Line-buffered with grep необходим, потому что иначе он будет буферизовать свой вывод, потому что канал не считается терминалом. Grep выведет такие строки:

Aug 29 11:56:01 localhost postfix/smtp[4124]: 05491500123: to=<someone@xyz.nl>, relay=123.456.123.456[123.456.123.456]:25, delay=2, delays=0.4/0/0.4/1.2, dsn=2.0.0, status=sent (250 2.0.0 u7T9twxN074009 Message accepted for delivery)

Первый разрез затем делает:

Aug 29 11:56:01 localhost postfix/smtp[4124]: 05491500123: to=<someone

Второй разрез должен генерировать:

someone

Однако, похоже, что сокращение также буферизуется. Если я запускаю команду с помощью cat вместо tail -f, я получаю все соответствующие результаты (в предпочтительном формате) из файла журнала. Но мне нужны результаты из файла журнала в режиме реального времени.

Я попытался использовать unbuffer для этого:

# tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | unbuffer cut -d '@' -f 1 | cut -d '<' -f 2

Также попробовал:

# unbuffer tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | unbuffer cut -d '@' -f 1 | cut -d '<' -f 2

... который должен удалить 4K буферизацию из первого среза . Тем не менее, это не работает. Я знаю, что это буферизация, потому что, если я использую grep для нашего локального домена, он получает гораздо больше обращений, буфер заполняется раньше, а выходные данные генерируются раньше (в пакетах по 4K).

Так что мой вопрос: как я unbuffer вырезать ?

Связано: я знаю, что sed и (g) awk могут доставлять мне адреса электронной почты. Я пытался, но пока безрезультатно. Ответы, использующие sed или (g) awk, приветствуются и могут решить мою прямую проблему, но я по-прежнему заинтересован в номинальном ответе на вопрос, как отменить буфер команды cut. Команда cut не говорит о (не) буферизации.

Вилобородый
источник
awk -F'[><@]' '/@xyz.nl/ {print $2}'...
Джейсонвриан
1
попробуйте grep -oP '[^<]+(?=@xyz.nl)'(вместе с другими опциями grep по мере необходимости)
Sundeep
Оба варианта awk и grep выше работают как шарм!
Forkbeard

Ответы:

16

Если вы работаете в системе, использующей GNU Coreutils (почти любой Linux), вы можете попробовать stdbuf:

… | stdbuf -oL cut -d '@' -f 1 | …

-oL делает его буферизованным, что похоже на то, что вы хотите.

derobert
источник
Это именно то, что я искал, спасибо!
Forkbeard
Ничего не меняет для меня почему-то. :(
Panzi
1
@panzi Не стесняйтесь задавать свой вопрос, ссылаясь на этот. Пожалуйста, включите полную информацию (точная команда, которую вы используете, если это возможно, ОС, дистрибутив, версия и т. Д.) Надеюсь, кто-то сможет выяснить, почему это не работает для вас.
Дероберт