tail -f일 때 grep 일치 항목 하나만 인쇄하는 방법은 무엇입니까?

tail -f일 때 grep 일치 항목 하나만 인쇄하는 방법은 무엇입니까?

활동 로그를 읽고 있으며 특별한 전화에 응답하려고 합니다.

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

그러나 일부 패턴은 개발 과정으로 인해 거의 인쇄되지 않았고 다른 패턴은 매우 지속적으로 인쇄되었습니다.

egrep패턴당 하나의 요청만 인쇄하여 제대로 작동하는지 쉽게 확인할 수 있는 방법은 무엇입니까 ?

답변1

다음을 수행할 수 있습니다.

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모든 모드가 표시되면 종료되지만 다음에 무언가가 기록될 때만 종료됩니다 ( tailSIGPIPE).

또는 행이 둘 이상의 패턴과 일치하지 않을 수 있고 모든 패턴을 찾은 후 종료하는 데 신경 쓰지 않는 경우 더 짧지만 효율성은 떨어집니다.

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

zshGNU를 사용하면 grep:

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

그러나 여러 패턴과 일치하는 줄은 여러 번 인쇄된다는 점에 유의하세요.

답변2

-o나중에 일치하는 부분만 인쇄할 것이라고 믿습니다 . 그런 다음 다음을 수행할 수 있습니다.

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

출력에 패턴이 포함되어 있으면 적어도 하나의 행이 패턴과 일치하기 때문입니다. 출력에 5개 패턴이 모두 포함된 경우 각 패턴은 최소한 한 줄과 일치합니다.

다른 문자와 일치하거나 다른 길이와 일치할 수 있는 정규식에서는 작동하지 않습니다.

답변3

또 다른 접근 방식은 다음과 같이 이전 패턴과 일치하는 각 패턴의 줄을 자체 줄에 출력하는 것입니다.

#! /bin/sh -
tput rmam # no line wrap for terminals that can do it
awk -v u="$(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...

예:

여기에 이미지 설명을 입력하세요.

관련 정보