3231|Block "5874: HTTP: .dat File Request"|192.168.11.254
3108|Block "5874: HTTP: .dat File Request"|192.168.11.253
3059|Block "5874: HTTP: .dat File Request"|192.168.11.250
3025|Block "5874: HTTP: .dat File Request"|192.168.11.251
2912|Block "5874: HTTP: .dat File Request"|192.168.11.252
分隔符为|
需求:1.当第二个字段 相同时对第一个字段进行求和,2.第二字段相同只能输出一行,第三个字段要合并到一行中
想要的结果:
15335|Block "5874: HTTP: .dat File Request"| 192.168.11.254/192.168.11.253/192.168.11.250…
用awk要怎么实现,有其他方法也可以,望大神指点。
[root@182 1]# awk 'BEGIN{FS=OFS="|"}{a[$2]+=$1;b[$2]=b[$2]$NF"/"}END{for(i in a)print a[i],i,b[i]}' file
15335|Block "5874: HTTP: .dat File Request"|192.168.11.254/192.168.11.253/192.168.11.250/192.168.11.251/192.168.11.252/
[root@182 1]# cat file
3231|Block "5874: HTTP: .dat File Request"|192.168.11.254
3108|Block "5874: HTTP: .dat File Request"|192.168.11.253
3059|Block "5874: HTTP: .dat File Request"|192.168.11.250
3025|Block "5874: HTTP: .dat File Request"|192.168.11.251
2912|Block "5874: HTTP: .dat File Request"|192.168.11.252
这么处理有个问题就是最后多了个/
man | grep了半天,勉强看懂了,简单记个笔记。
awk和file都是浮云,要解剖的是中间的单引号中的内容,可以分为三个部分。一、 由BEGIN引领的{}执行于真正的文本处理之前,可以对一些变量进行设定,方便接下来的处理。
就像我们吃饭之前,根据吃饭内容,将餐具设定为筷子、勺子或叉子一样。倘若不进行设定,用勺子吃面条,或用叉子吃咖喱饭,大概不会感觉很爽。
FS 是 F ield S eparator的缩写,表示文字处理时将以什么作为字段分隔符。 OFS 是 O utput FS 的缩写,表示文字处理后输出时将以什么作为字段分隔符。这里将二者都定义为管道符,可以理解为根据管道符分割字段,输出结果时保留原管道符。
二、 这个{}中是对文本真正进行处理的操作,就像我们吃饭时的“轻拢慢捻抹复挑”。
可以看到中间有个分号,整个处理分为两步,我们一步一步分析。
①a[$2]+=$1
注意到+=符号,这条语句等同于
a[$2]=a[$2]+$1
定义了一个数组a,每个不相同的第二字段都将成为它的一个元素,每种元素的第一字段总和为其值。
②b[$2]=b[$2]$NF"/"
NF 是 N umber of F ields的缩写,表示字段数量。$NF将输出“第‘字段数量’个字段”,即最后一个字段。
此语句定义了一个数组b,每个不相同的第二字段都将成为它的一个元素,每种元素的最后一个字段加上一个/符号,依次排列开,为其值。
三、 由END引领的{}执行于文本处理之后,一般用于按照自己喜欢的方式输出结果。
就像我们吃饭之后,有的小朋友跑去洗手,有的小朋友将手上的油抹到别人身上。 对a数组中的每个元素依次操作。 打印a数组中该元素的值,即原第一字段总和;元素,即原第二字段;b数组中该元素的值,即原第三字段排列。
两个数组的处理那里,我觉得我是明白的,但是好像说不清楚……
如果本楼有任何错误或您感觉理解困难的地方,欢迎指出。
四、
中间根据第二字段的值对ab两个数组进行操作,当第二字段相同时,对数组中同一个元素进行操作。
大概可以理解为巧妙地利用了数组元素的唯一性来过滤重复字段。