计算和排序文本文件列中的多个值

时间:2013-02-26 01:39:33

标签: sorting count awk grep text-files

我想筛选查找可疑活动的文本文件。我对bash脚本有点熟悉,包括grep,sed和awk。我对stackoverflow.com,tldp.org等的研究以及与同事的交流表明,perl和python最适合我的任务,但我对这些脚本语言没有经验。

欢迎使用各种脚本,编译或解释语言的输入。由于我的限制,请在代码中添加注释,使我能够快速理解和学习该语言。

好的,任务是对按列排序的项目进行排序和计数。我/可以/使用grep,awk和sed完成这一部分。不幸的是,递归方面(因为我发现问题)让我感到难过。

对输入文本进行排序,两列ip地址(在我的示例中简化,在下面)和一个目标端口列(所有可能的值)。此文件的大小可能是几兆字节,但可能不会超过250MB,因此绝对效率不是必需的。简单就是。

SIP        DIP        DPt
111.100    200.150    80
111.100    200.150    443
111.100    200.155    22
111.100    200.155    80
111.100    200.155    443
111.100    200.160    80
111.100    200.165    139
111.100    200.165    443
111.100    200.165    512
115.102    225.150    80
115.102    225.150    137
115.102    225.150    443
120.125    250.175    23
120.135    250.145    23
125.155    250.165    80
125.155    250.165    139
125.155    250.175    1023

我工作的代码(从内存中起草这个代码......目前不在我的linux机箱中)与此类似......

#!/bin/bash

declare -i counter=0
SIP=null       # current source ip.
SIP_last=null  # for last ip address processed.
SIP_next=null  # not found a use for this, yet. 
               # sorting usually reqs three vars, so here it is.

for SIP in `zcat textfile.gz | awk '{ if ($3 <1024) print $1,$2,$3}'` do
# Ensure I count the first item.  This was problematic at first.
if [[ "$SIP_last" == null ]] then
SIP_last=$SIP
counter=counter+1  # counter=+ didn't work reliably.

# Do something useful.  As shown, it works.
if [[ "$SIP" == "$SIP_last" ]] then
counter=counter+1

if [[ "$SIP != "$SIP_last" ]] then
echo SIP: $SIP_last     Counter: $counter   # DIP code has not yet been added.
SIP_last=$SIP

# Ensure I always catch the last item.  Still working on this issue.
# XXX

done

使用上面提供的输入,输出应该看起来像这样......

SIP      DIP Ct   Ports
         > 2      < 1024
111.100  200.150  80, 443
111.100  200.155  20, 80, 443
111.100  200.165  139, 443, 512
115.102  225.150  80, 137, 443

查看输出结果,您可以看到问题的症结仅在于报告DIP计数&gt; 2和端口&lt; 1024.将端口限制为&lt; 1024使用提供的awk语句很简单。它将DIP与SIP相匹配,并保持运行速度的DPts。

同样,这是来自内存,因此请原谅编码错误。谢谢你的帮助。

艾伦。

1 个答案:

答案 0 :(得分:1)

使用您发布的示例输入文件:

$ awk '
NR==1 { print; next }
$3 < 1024 {
   key = $1 "\t" $2
   if (!seen[key,$3]++) {
      cnt[key]++
      vals[key] = vals[key] sep[key] $3
      sep[key] = ", "
   }
}
END { for (key in cnt) if (cnt[key] > 1) print key "\t" vals[key] }
' file
SIP        DIP        DPt
111.100 200.155 22, 80, 443
111.100 200.165 139, 443, 512
125.155 250.165 80, 139
115.102 225.150 80, 137, 443
111.100 200.150 80, 443

如果那不是你想要的,请澄清。