如何在tail -f时仅打印一个grep匹配项?

tac*_*omi 5 grep text-processing

我正在阅读活动日志并尝试接到一些特殊电话

$ tail -f example.log | egrep 'pattern1|pattern2|pattern3|pattern4|pattern5'
Run Code Online (Sandbox Code Playgroud)

但是有几个图案几乎没有打印出来(由于开发流程),而另一个则非常连续地打印。

我怎样才能让egrep每个图案只打印一个请求,这样我就可以很容易地看到它们运行良好。

Sté*_*las 6

你可以这样做:

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}'
Run Code Online (Sandbox Code Playgroud)

请注意,awk它会在看到所有模式后立即tail退出,但仅在下次写入内容时才会退出(SIGPIPE)。

或者如果行可能不匹配多个模式,并且如果您不关心在找到所有模式时退出,则更短但效率较低:

awk '/pattern1/&&!a++ || /pattern2/&&!b++ || /pattern3/&&!c++ || \
     /pattern4/&&!d++ || /pattern5/&&!e++'
Run Code Online (Sandbox Code Playgroud)

随着zsh和GNU grep

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

但请注意,匹配多个模式的行将被打印多次。