如何在文本文件(Bash)中的列中查找元素总和

时间:2017-03-15 14:36:16

标签: bash unix awk sed

我有一个包含大量不必要信息的日志文件。该文件唯一重要的部分是描述一些统计信息的表。我的目标是有一个脚本,它接受一个列名作为参数,并返回指定列中所有元素的总和。

示例日志文件:

.........
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的内容,但未能找到解决方案。

3 个答案:

答案 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}分配给logfileattribute变量。
  • wc -w,计算该行内的字数 包含NAME${attribute}(字段索引)并将其分配给field
  • sed
    • 禁止自动打印(-n)并启用扩展正则表达式(-r
    • 查找NAMENOTE行之间的行,包括
    • 删除与NAMENOTE
    • 匹配的行
    • 将每个连续的空格运行转换为单个选项卡并打印结果
  • 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