如何在跟踪文件的同时对每个GREP结果执行命令

时间:2021-08-17 06:17:34

TL;DR: How to execute a command on each grep match that is produced while piping tail -f into grep.

DR:如何在管道尾部-f进入grep时,对所产生的每个grep匹配执行一个命令。

I am currently using tail -f file | grep exceptionto follow all the exceptions thrown by a service. One of the issues is that the line that has the exception doesn't have all the information I need, but it does contain an ID that identifies all the log lines generated by that request.

我目前正在使用tail -f文件| grep exceptionto跟踪服务抛出的所有异常。其中一个问题是具有异常的行没有我需要的所有信息,但它确实包含一个标识该请求生成的所有日志行的ID。

What I want to do is to to print all lines that have a certain ID once grep matches a line with exception.

我要做的是打印所有的行,它有一个ID,一旦grep与异常匹配。

Using the help from this question How to grep and execute a command (for every match)

使用这个问题的帮助,如何grep和执行命令(针对每个匹配)

I manage to make it work for the CAT command, like this:

我设法让它为CAT命令工作,就像这样:

cat myFile | 
egrep -i "exception" | #find lines with exception
egrep -o "ID=[A-Z]{10}" | #for those lines, select out only the id
while read line;  do #for each id
   cat myFile | grep $line; #show all the lines that have that id
done

that works fine and prints all the lines with matching ID, however when I change the cat to tail -f it wont work, it wont print anything. What am I doing wrong?

这样可以很好地打印所有的行,并且带有匹配的ID,但是当我把猫换成尾巴时——如果它不能工作,它就不能打印任何东西。我做错了什么?

1 个解决方案

#1


2  

The problem you're having is likely that grep is buffering its output when it sees that its output is another pipe. Your command might eventually produce output if you wait long enough for a buffer to fill up.

您遇到的问题可能是grep在看到输出是另一个管道时正在缓冲输出。如果您等待足够长的缓冲区来填充,您的命令可能最终会产生输出。

Instead, try the following:

相反,试试以下:

< myFile egrep --line-buffered -i "exception" \
| egrep --line-buffered -o "ID=[A-Z]{10}" \
| while read line; do
    cat myFile | grep "$line"
  done

(Yes, that input redirection option should work just fine. :] )

(是的,这个输入重定向选项应该没问题。:])

The relevant man page excerpt is:

有关的手册页摘录如下:

   --line-buffered
          Use line buffering on output.  This can cause a performance penalty.

which obviously wouldn't have helped you much unless you knew what you were looking for. :-P

如果你不知道你在找什么,这显然对你没有多大帮助。:- p

Note that in the Linux world, you're using Linux, where your man page probably states that "Direct invocation as either egrep or fgrep is deprecated, but is provided to allow historical applications that rely on them to run unmodified." Though to be honest, I don't see egrep ever disappearing, and other platforms (FreeBSD, OSX) make no mention of deprecation.

注意,在Linux世界中,您使用的是Linux,您的手册页可能会声明“不赞成直接调用作为白鹭或fgrep,但允许依赖它们的历史应用程序运行未经修改的。”虽然说实话,我不认为鹭会消失,其他平台(FreeBSD, OSX)也没有提到弃用。

#1


2  

The problem you're having is likely that grep is buffering its output when it sees that its output is another pipe. Your command might eventually produce output if you wait long enough for a buffer to fill up.

您遇到的问题可能是grep在看到输出是另一个管道时正在缓冲输出。如果您等待足够长的缓冲区来填充,您的命令可能最终会产生输出。

Instead, try the following:

相反,试试以下:

< myFile egrep --line-buffered -i "exception" \
| egrep --line-buffered -o "ID=[A-Z]{10}" \
| while read line; do
    cat myFile | grep "$line"
  done

(Yes, that input redirection option should work just fine. :] )

(是的,这个输入重定向选项应该没问题。:])

The relevant man page excerpt is:

有关的手册页摘录如下:

   --line-buffered
          Use line buffering on output.  This can cause a performance penalty.

which obviously wouldn't have helped you much unless you knew what you were looking for. :-P

如果你不知道你在找什么,这显然对你没有多大帮助。:- p

Note that in the Linux world, you're using Linux, where your man page probably states that "Direct invocation as either egrep or fgrep is deprecated, but is provided to allow historical applications that rely on them to run unmodified." Though to be honest, I don't see egrep ever disappearing, and other platforms (FreeBSD, OSX) make no mention of deprecation.

注意,在Linux世界中,您使用的是Linux,您的手册页可能会声明“不赞成直接调用作为白鹭或fgrep,但允许依赖它们的历史应用程序运行未经修改的。”虽然说实话,我不认为鹭会消失,其他平台(FreeBSD, OSX)也没有提到弃用。