我有以下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中处理它。在此例程中可以忽略其他类型的问题。谁能提供有关如何做到这一点的建议?我想读取每一行,直到我基本上达到下一个错误,并将该数据放入某种数据结构中。
答案 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
我从来没有看过比The AWK Manual更远的地方。
如果对列名称列表和数据使用了一致的字段分隔符,这将使事情变得更容易。也许您可以使用bash
在sed
脚本中进行一些预处理,然后再转到awk
。无论如何,请查看手册中的multi-dimensional arrays
和reading 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