Скрипт Bash, который анализирует файлы отчетов - PullRequest
2 голосов
/ 14 декабря 2010

У меня есть следующий скрипт 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
   .
   .
   .

Iищу способ просмотреть каждый файл и агрегировать данные отчета.В приведенном выше примере у нас есть две уникальные проблемы типа X, которые я хотел бы решить в analyStructural.Другие типы проблем могут быть проигнорированы в этой процедуре.Кто-нибудь может дать совет, как это сделать?Я хочу читать каждую строку до тех пор, пока не достигну следующей ошибки, и поместить эти данные в некую структуру данных.

Ответы [ 3 ]

3 голосов
/ 15 декабря 2010

Ниже приведена рабочая реализация 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 голос
/ 15 декабря 2010

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
1 голос
/ 15 декабря 2010

Как предположил Дэйв Джарвис, awk будет:

  • справиться с этим лучше, чем bash
  • довольно легко выучить
  • вероятно доступно везде, где доступен bash

Мне никогда не приходилось смотреть дальше, чем Руководство по AWK .

Было бы проще, если бы вы использовали непротиворечивый разделитель полей как для списка имен столбцов, так и для данных. Возможно, вы могли бы выполнить некоторую предварительную обработку в сценарии bash, используя sed, прежде чем передать awk. В любом случае, посмотрите на multi-dimensional arrays и reading multiple lines в руководстве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...