首页 > 解决方案 > 这些 awk 操作可以组合/优化,还是以不同的方式完成?

问题描述

我将三个 awk 串在一起,似乎可以满足我的需要,但是可以更有效/完全不同地完成吗?

目前分三个阶段:

  1. 快速检查字段 2 是否包含 IP 或 FQDN
  2. 反转 FQDN 的最后(最多)三个元素
  3. 聚合字段配对的出现次数
awk '$2~/[a-z,A-Z,0-9]\.[a-z,A-Z]+$/{print$2,$1,$3}' ???.20201001.txt|awk '{n=split($1,a,".");for(i=0;i<3&&i<n;i++)printf ".%s",a[n-i];print"",$2,$3}'|[$1 " " $2] +=$3} END {for(i in combo) print i, combo[i]}'> combos.20201001.txt

在被解析的日志中,字段是:

  1. IP地址
  2. 全域名
  3. 数数

"

An input file consisting of: 
1.2.3.5 four.three.two.com 14
1.2.3.5 four.three.two.com 34
1.2.3.5 different.biz 12
7.8.9.1 four.three.two.com 5


should output:
.biz.different 1.2.3.5 12
.com.two.three 1.2.3.5 48
.com.two.three 7.8.9.1 5

"

行输出的顺序并不重要(排序工作),缩写的 FQDN 已从行的中间移动到行前的唯一原因是这是我可以让我的 awk 输出三个字段的唯一方法在同一条线上。

"

1.2.3.5 .biz.different 12
1.2.3.5 .one.two.three 48
7.8.9.1 .one.two.three 5

"

可以接受,甚至更可取。为格式化道歉;这有点挑战。

标签: optimizationawk

解决方案


$ cat tst.awk
$2 ~ /[[:alnum:]]\.[[:alpha:]]+$/ {
    end = split($2,parts,/[.]/)
    beg = end - 2
    beg = (beg>0 ? beg : 1)
    for (i=beg; i<=end; i++) {
        fqdn = parts[i] (i == beg ? "" : "." fqdn)
    }
    key = $1 OFS fqdn
    count[key] += $3
}
END {
    for (key in count) {
        print key, count[key]
    }
}

$ awk -f tst.awk file
7.8.9.1 one.two.three 5
1.2.3.5 one.different 12
1.2.3.5 one.two.three 48

推荐阅读