Как печатать только одно совпадение grep, когда tail -f?

Я читаю активный журнал и пытаюсь получить специальные звонки

$ tail -f example.log | egrep 'pattern1|pattern2|pattern3|pattern4|pattern5' 

Но несколько шаблонов едва напечатаны (из-за потока dev), а другие очень непрерывно печатаются.

Как заставить egrep печатать только один запрос для каждого шаблона, чтобы я мог легко видеть, что они отлично работают.

3 Solutions collect form web for “Как печатать только одно совпадение grep, когда tail -f?”

Вы могли бы сделать что-то вроде:

 tail -f example.log | awk ' BEGIN { n = split("pattern1,pattern2,pattern3,pattern4,pattern5", pats, /,/) } { found=0 for (i in pats) if ($0 ~ pats[i]) { found=1 delete pats[i] n-- } } found {print; if (!n) exit}' , tail -f example.log | awk ' BEGIN { n = split("pattern1,pattern2,pattern3,pattern4,pattern5", pats, /,/) } { found=0 for (i in pats) if ($0 ~ pats[i]) { found=1 delete pats[i] n-- } } found {print; if (!n) exit}' 

Обратите внимание, что awk выйдет, как только он увидит все шаблоны, но tail выйдет только (из SIGPIPE) только в следующий раз, когда он что-то напишет после этого.

Или если строки могут не совпадать с несколькими шаблонами, и если вы не заботитесь о выходе, когда все шаблоны найдены, более короткие, но менее эффективные:

 awk '/pattern1/&&!a++ || /pattern2/&&!b++ || /pattern3/&&!c++ || \ /pattern4/&&!d++ || /pattern5/&&!e++' 

С zsh и GNU grep :

 (trap '' PIPE;tail -f example.log > >(grep -m1 pattern1) \ > >(grep -m1 pattern2) \ > >(grep -m1 pattern3) \ > >(grep -m1 pattern4) \ > >(grep -m1 pattern5)) 

Но обратите внимание, что строки, соответствующие нескольким шаблонам, будут напечатаны столько раз.

Я считаю, что вы после -o который будет печатать только согласованную часть. Затем вы можете сделать следующее:

 cat example.log | egrep -o 'pat1|pat2|pat3|pat4|pat5' | sort | uniq 

Если выход содержит шаблон, это связано с тем, что по крайней мере одна строка соответствует этому шаблону. Если вывод содержит все 5 шаблонов, каждый шаблон соответствует по меньшей мере одной строке.

Не работает с регулярными выражениями, которые могут совпадать с разными символами или разными совпадениями по длине.

Другим подходом может быть вывод строк, соответствующих каждому шаблону, по сравнению с предыдущим в своей собственной строке, например:

 #! /bin/sh tput rmam # no line wrap for terminals that can do it awk -vu="$(tput cuu1)" -v el="$(tput el)" ' BEGIN { for (n = 0; n < ARGC; n++) pat[n] = ARGV[n] ARGC=0 } { pre = ""; post = el "\r" u for (i = 1; i < n; i++) { if ($0 ~ pat[i]) print pre $0 post pre = pre "\n" post = post u } } END{printf "%s", pre}' "$@" tput smam 

Вызывается как:

 tail -f example.log | that-script pattern1 pattern2... 

Пример:

введите описание изображения здесь

  • В чем разница между \ b и \ <в команде grep
  • Как совместить число в одном файле с именем в другом файле?
  • Результаты трубы grep в поиске
  • Как объединить grep с несколькими аргументами и разными выходными переключателями
  • Извлечение списка шаблонов, которые выводятся из другой команды
  • фильтровать данные по значению столбца
  • Как grep -v, а также исключить следующую строку после матча?
  • Как вы можете перемещать (или копировать) все файлы определенного типа в каталог в Unix?
  • Почему мое grep + regex не работает?
  • Помощь с использованием кавычек в поиске grep
  • Как мне grep и сортировать с помощью этого конкретного шаблона?
  • grep для извлечения подстрок в строке
  • Linux и Unix - лучшая ОС в мире.