用于分析报告文件的Bash脚本

时间:2010-12-14 19:57:52

标签: bash reporting

我有以下bash脚本,我将用它来分析当前目录中的所有报告文件:

#!/bin/bash    


# methods
analyzeStructuralErrors()
{ 
    # do something with $1
}

# main
reportFiles=`find $PWD -name "*_report*.txt"`; 
for f in $reportFiles
do
    echo "Processing $f"
    analyzeStructuralErrors $f
done

我的报告文件格式如下:

Error Code for Issue X - Description Text - Number of errors.
col1_name,col2_name,col3_name,col4_name,col5_name,col6_name
   1143-1-1411-247-1-72953-1
   1143-2-1411-247-436-72953-1
   2211-1-1888-204-442-22222-1
Error Code for Issue Y - Description Text - Number of errors.
col1_name,col2_name,col3_name,col4_name,col5_name,col6_name
   Other data
   .
   .
   .

我正在寻找一种方法来浏览每个文件并汇总报告数据。在上面的例子中,我们有两个类型为X的独特问题,我想在analyzeStructural中处理它。在此例程中可以忽略其他类型的问题。谁能提供有关如何做到这一点的建议?我想读取每一行,直到我基本上达到下一个错误,并将该数据放入某种数据结构中。

3 个答案:

答案 0 :(得分:3)

下面是一个使用它的伪多维数组的工作awk实现。我已经包含了示例输出,以向您展示它的外观。我冒昧地添加一个“计数”列来表示针对给定错误代码命中某个“问题”的次数

#!/bin/bash

awk '
 /Error Code for Issue/ {
   errCode[currCode=$5]=$5
 }
 /^ +[0-9-]+$/ {
   split($0, tmpArr, "-")
   error[errCode[currCode],tmpArr[1]]++
 }
 END {
   for (code in errCode) {
     printf("Error Code: %s\n", code)
     for (item in error) {
       split(item, subscr, SUBSEP)
       if (subscr[1] == code) {
         printf("\tIssue: %s\tCount: %s\n", subscr[2], error[item])
       }
     }
   }
 }
' *_report*.txt

输出

$ ./report.awk
Error Code: B
        Issue:    1212  Count: 3
Error Code: X
        Issue:    2211  Count: 1
        Issue:    1143  Count: 2
Error Code: Y
        Issue:    2961  Count: 1
        Issue:    6666  Count: 1
        Issue:    5555  Count: 2
        Issue:    5911  Count: 1
        Issue:    4949  Count: 1
Error Code: Z
        Issue:    2222  Count: 1
        Issue:    1111  Count: 1
        Issue:    2323  Count: 2
        Issue:    3333  Count: 1
        Issue:    1212  Count: 1

答案 1 :(得分:1)

根据Dave Jarvis的建议,awk将:

  • 处理此问题比bash
  • 更好
  • 相当容易学习
  • 可能在bash可用的地方提供

我从来没有看过比The AWK Manual更远的地方。

如果对列名称列表和数据使用了一致的字段分隔符,这将使事情变得更容易。也许您可以使用bashsed脚本中进行一些预处理,然后再转到awk。无论如何,请查看手册中的multi-dimensional arraysreading multiple lines

答案 2 :(得分:1)

Bash具有由整数索引的一维数组。 Bash 4添加了关联数组。这就是数据结构。 AWK具有一维关联数组,并通过二维数组伪装。如果您需要某种比这更先进的数据结构,您需要使用Python,例如,或其他语言。

也就是说,这是一个粗略的概述,说明如何解析你所显示的数据。

#!/bin/bash    

# methods
analyzeStructuralErrors()
{ 
    local f=$1
    local Xpat="Error Code for Issue X"
    local notXpat="Error Code for Issue [^X]"
    while read -r line
    do
        if [[ $line =~ $Xpat ]]
        then
            flag=true
        elif [[ $line =~ $notXpat ]]
        then
            flag=false
        elif $flag && [[ $line =~ , ]]
        then
            # columns could be overwritten if there are more than one X section
            IFS=, read -ra columns <<< "$line"
        elif $flag && [[ $line =~ - ]]
        then
            issues+=(line)
        else
            echo "unrecognized data line"
            echo "$line"
        fi
    done

    for issue in ${issues[@]}
    do
        IFS=- read -ra array <<< "$line"
        # do something with ${array[0]}, ${array[1]}, etc.
        # or iterate
        for field in ${array[@]}
        do
            # do something with $field
        done
    done
}

# main
find . -name "*_report*.txt" | while read -r f
do
    echo "Processing $f"
    analyzeStructuralErrors "$f"
done