免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2322 | 回复: 3
打印 上一主题 下一主题

perl文件操作-请教 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-09-19 13:28 |只看该作者 |倒序浏览
现在有这样一个情况
假设在任意一个目录(比如/var/log/monitor_network)下很多个文件,文件的名字存储在@f_final_list里。
每个文件的内容都类似如下
dst             src             cnt      o_r  
1.0.0.26     1.0.0.22     5        100
1.1.1.1        2.2.2.2      7         10
..........


第一行,dst(目的地址)、src(源地址)、cnt(TCP连接的个数)、o_r(重传数据包的个数);
第二行,是个模拟数据。
目标如下:
1.需要根据脚本运行时(比如./1.pl ipaddr)传入的IP地址参数,可以找到在文件列表里src那列对应Ip地址和传入的参数相同的行。
2.然后能够在文件列表(@f_final_list)里(文件列表当然包括很多文件了)进行两两比较。比如找到了1.0.0.22那行,另外一个文件里也有这样的1.0.0.22的记录,然后就比较它们的cnt下面的数值,比较出大小后,可以随意打印下就好。
比如文件A
dst             src             cnt      o_r  
1.0.0.26    1.0.0.22     5        100
1.1.1.1        2.2.2.2      7         10
..........
文件B
dst             src             cnt      o_r  
1.0.0.27     1.0.0.22     20       101
3.3.3.3        4.4.4.4      30       200
..........

论坛徽章:
0
2 [报告]
发表于 2010-09-19 13:31 |只看该作者
当然,最重要的是高手,可以组织下数据结构等高深的东西,在上面的示例文件里,就类似linux操作系统 /proc目录下,第一行是标题栏,可以当成哈希表里的键,下面对应的是值

论坛徽章:
0
3 [报告]
发表于 2010-09-19 13:37 |只看该作者
#!/usr/bin/perl
use strict;
use warnings;
die "Usage: $0 [ipaddr]\n"if(@ARGV < 1);
my $ipaddr = $ARGV[0];
print "$ipaddr\n";
if(!($ipaddr =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&
        (($1>=0)&&($1<255)&&($2>=0)&&($2<255)&&($3>=0)&&($3<255)&&($4>=0)&&($4<255))))
{
        die "Invalid Argument \n";
}
print "$1-$2-$3-$4\n";

my $now = `date +%s`;
my $year = `date +%y`;
my $month = `date +%m`;
my $day = `date +%d`;
my $hour = `date +%H`;
my $min = `date +%M`;
my $sec = `date +%S`;
chomp($now);
chomp($year);
chomp($month);
chomp($day);
chomp($hour);
chomp($min);
chomp($sec);
print "$now-$year-$month-$day-$hour-$min-$sec\n";


my $dir_to_process = "/var/log/monitor_network";
my @f_pro_list;
opendir DH,$dir_to_process or die "Can't open $dir_to_process. $!\n";
while(my $file = readdir DH)
{
        next if($file eq "." || $file eq "..");
        print "$file\n";
        $file=~ /^\w+_\w+_(\d+)_(\d+)_(\d+)_(\d+)_(\d+)_(\d+)$/;
        print "<-$1,$2,$3,$4,$5,$6->\n";
        if($year < $1){   
                 next;
        }
        elsif($year == $1){
                if($month < $2){next}
                elsif($month == $2){
                        if($day < $3){next}
                        elsif($day == $3){
                                if($hour < $4){next}
                                elsif($hour == $4){
                                        if($min < $5){next}
                                        elsif($min == $5){
                                                if($sec < $6){next}
                                                elsif($sec){next}   #exceptions
                                                else{
                                                        push @f_pro_list,$file;
                                                }
                                        }
                                        else{
                                                push @f_pro_list,$file;
                                        }

                                }
                                else{
                                        push @f_pro_list,$file;
                                }
                        }
                        else{
                                push @f_pro_list,$file;
                        }
                }
                else{
                        push @f_pro_list,$file;
                }
        }
        else{
                push @f_pro_list,$file;
        }
}
closedir DH;
my @f_final_list;
my $row = 0;
my $col;
my $hashref;
my $ip_matched = 0;
my @keys;
my @f_final_list;
chdir "/var/log/monitor_network/" or die "Can't chdir,error: $!\n";
foreach my $pro_file (@f_pro_list)
{
        open FH,$pro_file or die "Can't open $pro_file: $!\n";
        while(<FH>)
        {
                chomp;
                my @temp = split;
                if($row == 0){
                        @keys = @temp;
                        $col = scalar @keys;
                        #print "col = $col, $pro_file\n"
                }
                else{
                        my %temp_hash;
                        for(my $i=0;$i<$col;$i++)
                        {
                                $temp_hash{$keys[$i]} = $temp[$i];
                                if(($keys[$i] =~ /^src$/) &&($temp_hash{$keys[$i]} eq $ARGV[0])){
                                        $ip_matched++;
                                        print "$ip_matched---$_---\n";
                                }
                        }
                        push @$hashref,{%temp_hash};
                }
                $row++;
        }
        if($ip_matched > 0){
                push @f_final_list,$pro_file;
        }
        $row = 0;
        $ip_matched = 0;
        close FH;
}
foreach(@f_final_list)
{
        print "<>---$_---<>\n";
        open FH,$_ or die "Can't Open $_: $!\n";
        while(<FH>)
        {
                print;
        }
        close FH;
}


上面的是自己写的一些过滤出文件列表的代码部分,但是下面的比较部分没有思路了,如何两两比较文件里的一些字段,对于@f_final_list这个数组,还请高手指点下,谢谢。。。

论坛徽章:
0
4 [报告]
发表于 2010-09-19 15:43 |只看该作者
本帖最后由 珞水的大叔 于 2010-09-19 15:45 编辑

……
我有种奇怪的感觉,为什么你的需求都比较适合用数据库呐

而且如果只需要满足你那两个需求的话
不如就用grep:
  1. for(@f_final_list){   #@f_final_list 里面放文件名
  2.     system("grep ipaddr $_");
  3. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP