我想要做的是根据 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