通过多个 grep 命令过滤 tail 命令来分隔文件

通过多个 grep 命令过滤 tail 命令来分隔文件

我想要做的是根据 grep 过滤器将一个日志文件的输出过滤为单独的日志文件。

tail -f test.log | tee >(grep "错误" > error.log) >(grep "警告" > warning.log)

这样,所有“错误”条目都在一个文件中,而所有“警告”条目都在单独的文件中。

我知道这在概念上是可行的,因为如果我使用代替尾巴,我得到了正确的文件输出,但无法实时跟踪变化(我需要这样做,因为我正在观察正在运行的测试的输出日志)

另外,如果我从中删除'>'文件重定向器grep命令它会将各个 grep 输出正确地输出到控制台;但是,我也想要一个记录的文件。

回答:

当写入文件时grep正在缓冲。使用egrep--line-buffer选项修复了该行为。

新的命令如下:

tail -f test.log | tee >(egrep --line-buffered "ERROR" > error.log) >(egrep --line-buffered "WARNING" > warning.log)

答案1

如果你使用多行来执行此操作可能会更容易。你可以编写一个 bash 脚本:

#!/bin/bash

tail -f test.log | while read line; do
    if echo "$line" | grep -q "Error"; then
        echo "$line" >> error.log
    elif echo "$line" | grep -q "Warning"; then
        echo "$line" >> warning.log
    # The following is in case you want to print out lines that do not match 
    else
        echo "$line"
    fi
done

答案2

@Ryan,感谢您回答您的问题。
设置每行缓冲的另一种(通用)方法是使用stdbuf命令:

tail -f test.log | tee >(stdbuf -oL grep "ERROR" > error.log) >(stdbuf -oL grep "WARNING" > warning.log)

以下为摘录man stdbuf

SYNOPSIS
   stdbuf OPTION... COMMAND
...
   -o, --output=MODE
          adjust standard output stream buffering
...
   If MODE is 'L' the corresponding stream will be line buffered.
....
EXAMPLES
   tail -f access.log | stdbuf -oL cut -d ' ' -f1 | uniq
   This will immedidately display unique entries from access.log

相关内容