在 Linux 上检测子文件夹中包含特定字符串的多个文件

在 Linux 上检测子文件夹中包含特定字符串的多个文件

我在不同的子文件夹中有多个 work.log 文件,需要检测两个关键字Can't find fileNot 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

相关内容