Я хочу получить только адреса электронной почты, которые заканчиваются на "@ 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}'
...grep -oP '[^<]+(?=@xyz.nl)'
(вместе с другими опциями grep по мере необходимости)Ответы:
Если вы работаете в системе, использующей GNU Coreutils (почти любой Linux), вы можете попробовать
stdbuf
:-oL
делает его буферизованным, что похоже на то, что вы хотите.источник