我有一个包含大量不必要信息的日志文件。该文件唯一重要的部分是描述一些统计信息的表。我的目标是有一个脚本,它接受一个列名作为参数,并返回指定列中所有元素的总和。
示例日志文件:
.........
Skipped....
........
WARNING: [AA[409]: Some bad thing happened.
--- TOOL_A: READING COMPLETED. CPU TIME = 0 REAL TIME = 2
--------------------------------------------------------------------------------
----- TOOL_A statistics -----
--------------------------------------------------------------------------------
NAME Attr1 Attr2 Attr3 Attr4 Attr5
--------------------------------------------------------------------------------
AAA 885 0 0 0 0
AAAA2 1 0 2 0 0
AAAA4 0 0 2 0 0
AAAA8 0 0 2 0 0
AAAA16 0 0 2 0 0
AAAA1 0 0 2 0 0
AAAA8 0 0 23 0 0
AAAAAAA4 0 0 18 0 0
AAAA2 0 0 14 0 0
AAAAAA2 0 0 21 0 0
AAAAA4 0 0 23 0 0
AAAAA1 0 0 47 0 0
AAAAAA1 2 0 26 0
NOTE: Some notes
......
Skipped ......
预期使用量script.sh Attr1
预期产量:
888
我试图找到sed/awk
的内容,但未能找到解决方案。
答案 0 :(得分:1)
tldr;
$ cat myscript.sh
#!/bin/sh
logfile=${1}
attribute=${2}
field=$(grep -o "NAME.\+${attribute}" ${logfile} | wc -w)
sed -nre '/NAME/,/NOTE/{/NAME/d;/NOTE/d;s/\s+/\t/gp;}' ${logfile} | \
cut -f${field} | \
paste -sd+ | \
bc
$ ./myscript.sh mylog.log Attr3
182
说明:
${1}
和${2}
分配给logfile
和attribute
变量。wc -w
,计算该行内的字数
包含NAME
和${attribute}
(字段索引)并将其分配给field
sed
-n
)并启用扩展正则表达式(-r
)NAME
和NOTE
行之间的行,包括NAME
和NOTE
cut
使用字段索引paste
所有数字作为中缀求和bc
答案 1 :(得分:0)
快速而肮脏(没有任何其他规格)
awk -v CountCol=2 '/^[^[:blank:]]/ && NF == 6 { S += $( CountCol) } END{ print S + 0 }' YourFile
列名
awk -v ColName='Attr1' '/^[[:blank:]]/ && NF == 6 { for(i=1;i<=NF;i++){if ( $i == ColName) CountCol = i } /^[^[:blank:]]/ && NF == 6 && CountCol{ S += $( CountCol) } END{ print S + 0 }' YourFile
你应该添加一个标题/预告片过滤器,以避免嘈杂的线(一个适合这个的标志),但缺乏关于设置此标志的结构的信息,我使用简单的字段计数(假设文本字段有0作为值,所以不在计数中改变总和)
答案 2 :(得分:0)
$ awk -v col='Attr3' '/NAME/{for (i=1;i<=NF;i++) f[$i]=i} col in f{sum+=$(f[col]); if (!NF) {print sum+0; exit} }' file
182