我在不同的子文件夹中有多个 work.log 文件,需要检测两个关键字Can't find file
或Not pass by number
直接路径如:
/folder/Date/Job1/20190116_ADMtest_1/ADM.log
/folder/Date/Job1/20190122_ADMtest_2/ADM.log
/folder/Date/Job1/20190203_ADMtest_4/ADM.log
/folder/Date/Job1/20190217_ADMtest_3/ADM.log
/folder/Date/Job1/20190218_ADMtest_21/ADM.log
/folder/Date/Job1/20190225_ADMtest_18/ADM.log
每个日志看起来都会像这样:
[Message] 2019-01-16 11:13:21 Read 2 files from: 20190116_ADMtest_1txt
[Message] 2019-01-16 11:13:21
[Message] 2019-01-16 11:13:21 FATAL ERROR:Can't find file
[ERROR] 2019-01-16 11:13:21 ERROR Message : Stop
或者类似
[Message] 2019-01-22 10:56:06 # LOG 1 867 | Runtime: 0 hours 15 minutes and 45 seconds.
[Message] 2019-01-22 10:56:06 # Message 1 867 |
[Message] 2019-01-22 10:56:06 # Message 2 152 |
[Message] 2019-01-22 10:56:06 Average number: 58.534678
[ERROR] 2019-01-22 10:56:06 The file failed average number: Average number = 58.534678
我想要获取一个列表来了解哪些子文件夹有 ErrorICan't find file
以及哪些子文件夹有 ErrorIINot pass by number
期望输出如下:
ErrorI.txt
20190116_ADMtest_1
20190203_ADMtest_4
20190225_ADMtest_18
ErrorII.txt
20190122_ADMtest_2
20190217_ADMtest_3
20190218_ADMtest_21
答案1
下面是一个脚本,用于搜索您提到的两个字符串(请注意,第二个字符串实际上并不存在您的示例中),并创建两个输出文件,每个错误一个,其中包含匹配目录的列表:
## Delete any already existing output files
rm error1.txt error2.txt 2>/dev/null;
## define the error strings to search for
error1="Can't find file"
error2="Not pass by number"
## Iterate over all AMP.log files
for f in /folder/Date/Job1/*/AMP.log; do
if grep -q "$error1" "$f"; then
printf '%s\n' "${f%/*}" >> error1.txt
elif grep -q "$error2" "$f"; then
printf '%s\n' "${f%/*}" >> error2.txt
fi
done
我使用这些示例输入文件进行了测试:
$ for f in folder/Date/Job1/20190*/*log; do echo "===== $f ===="; cat "$f"; done
===== folder/Date/Job1/20190116_ADMtest_1/AMP.log ====
Can't find file
===== folder/Date/Job1/20190122_ADMtest_2/AMP.log ====
Not pass by number
===== folder/Date/Job1/20190203_ADMtest_4/AMP.log ====
Not pass by number
===== folder/Date/Job1/20190217_ADMtest_3/AMP.log ====
Can't find file
===== folder/Date/Job1/20190218_ADMtest_21/AMP.log ====
Can't find file
===== folder/Date/Job1/20190225_ADMtest_18/AMP.log ====
Not pass by number
并得到以下两个输出文件:
$ cat error1.txt
/folder/Date/Job1/20190116_ADMtest_1
/folder/Date/Job1/20190217_ADMtest_3
/folder/Date/Job1/20190218_ADMtest_21
$ cat error2.txt
/folder/Date/Job1/20190122_ADMtest_2
/folder/Date/Job1/20190203_ADMtest_4
/folder/Date/Job1/20190225_ADMtest_18
答案2
在bash
...同样自动化和高效(硬组合)我现在能想到的...也许这就是你所需要的:
{
declare -A e=( [ErrorI]="Can't find file" [ErrorII]="Not pass by number" )
for i in "${!e[@]}"; do
grep -rlm1 "${e[$i]}" /folder/Date/Job1/ |
awk -F'/' '{print $(NF-1)}' > "${i}.txt"
done
}
它将在当前工作目录中创建两个文件:ErrorI.txt
和,ErrorII.txt
内容如下:
$ cat ErrorI.txt
20190116_ADMtest_1
20190203_ADMtest_4
20190225_ADMtest_18
$ cat ErrorII.txt
20190122_ADMtest_2
20190217_ADMtest_3
20190218_ADMtest_21