我曾问过一个问题不久前关于如何从日志文件中提取特定信息,并得到了一些有用的答案,但我还没有完全得到我需要的东西。到目前为止我所拥有的:
#!/bin/bash
mkdir result
cd $1
ls | while read -r file;
do
egrep "ERROR|FAIL|WARN" > ../errors-$file
done
cd ..
mv errors-* result
这就是我想要的:脚本扫描日志目录,抓取包含 ERROR|FAIL|WARN 的每一行文本(有些是多行),并将它们与每个单独的文件一起输出到名为“result”的目录中根据其源文件命名。
当我的目标日志目录中只有一个文本文件时它可以工作,但当我的目标目录中包含不同级别的目录和日志文件时它不起作用。我知道这是因为脚本中的“../errors-$file”位,但我不知道如何更改它。
任何帮助都会很棒,如果措辞不当,我提前道歉。
答案1
我将研究你的循环本身,并尝试了解它实际在做什么,然后看看如何实现你想要的。
如何启动循环过于复杂:ls | while read -r file;
。您将结果通过管道传输ls
到您的while read
,这没什么大不了的,仍然有效,尽管我会推荐一个for
更像这样的循环:
for file in ./* ;
这将循环遍历相同的文件,但更直接一些。此外,该ls
命令可以返回的输出不仅仅是文件名(是否注意到ls
目录/可执行文件具有不同的字体颜色?),这可能会导致其他命令的麻烦。
您的命令:egrep "ERROR|FAIL|WARN" > ../errors-$file
正在尝试egrep
执行ERROR|FAIL|WARN
任何操作,并将输出重定向到../errors-$file
.
的语法egrep
是:
egrep [search pattern] [location]
egrep
所以你错过了要查看的位置。你可以通过$file
在模式后面添加来解决这个问题,所以它变成:
#!/bin/bash
mkdir result
cd $1
for file in $(find ./ -type f)
do
egrep "ERROR|FAIL|WARN" $file > ../result/errors-$(basename $file)
echo "-------------------------------" >> ../result/errors-$(basename $file)
egrep "denied" -B 1 $file >> ../result/errors-$(basename $file)
done