+ -
当前位置:首页 → 问答吧 → perl-问题请教

perl-问题请教

时间:2010-09-16

来源:互联网

Hello,请教个问题。
程序脚本如下:

#!/usr/bin/perl
use strict;
use warnings;                                                                                                                       
if(@ARGV < 1)
{
        die "Usage: $0 [Filename]\n";
}
my $file = $ARGV[0];
open FH,"<",$file or die "Can't open $file: $!\n";
my (@a,$row,$col,$i,$j);
while(<FH>)
{
        my @b = split;
        push @a,[@b];
        $col = @b;
        $row++;
}
close(FH);
print "$row,$col\n";
for($i=0;$i<$row;$i++)
{
        for($j=0;$j<$col;$j++)
        {
                print "...$a[$i][$j]...\n";
        }
}
print "\t\t\t$a[3][0]\n";
if($a[3][0]=~ /(\d+).(\d+).(\d+).(\d+)/)
{
        print "-$1-$2-$3-$4-\n";
}
my $hashref = [
        {
                $a[0][0]=>$a[1][0],
                $a[0][1]=>$a[1][1],
                $a[0][2]=>$a[1][2],
                $a[0][3]=>$a[1][3],
                $a[0][4]=>$a[1][4],
        },
        {
                $a[0][0]=>$a[2][0],
                $a[0][1]=>$a[2][1],
                $a[0][2]=>$a[2][2],
                $a[0][3]=>$a[2][3],
                $a[0][4]=>$a[2][4],
        },
        {
                $a[0][0]=>$a[3][0],
                $a[0][1]=>$a[3][1],
                $a[0][2]=>$a[3][2],
                $a[0][3]=>$a[3][3],
                $a[0][4]=>$a[3][4],
        },      
];
print "$hashref->[1]->{$a[0][0]}\n";  


测试文件:peer_conn_stat,文件内容如下

a               b       c       d       e                                                                                          
1               2       3       4       5
6               7       8       9       10
1.0.0.22        m       n       p       q
目的:实现打印文件peer_conn_stat的内容,并能够根绝里面的一些值做些数据统计之类的活。
状况:现在已经实现了用数组,和哈希数组引用打印里面的内容,但哈希数组的可扩展性不行(当peer_conn_stat的内容有大幅增加时)。
请教:请好心人帮忙用另外的方法实现哈希数组引用那部分,一定需要考虑可扩展性,也就是优化。(比如foreach $key (keys % hash)...组合),请高手帮忙实现之,谢谢。。

作者: peking_A_Liang   发布时间: 2010-09-16

补充下:脚本运行./1.pl peer_conn_stat

作者: peking_A_Liang   发布时间: 2010-09-16

my $hashref = [
        {
                $a[0][0]=>$a[1][0],
                $a[0][1]=>$a[1][1],
                $a[0][2]=>$a[1][2],
                $a[0][3]=>$a[1][3],
                $a[0][4]=>$a[1][4],
        },
        {
                $a[0][0]=>$a[2][0],
                $a[0][1]=>$a[2][1],
                $a[0][2]=>$a[2][2],
                $a[0][3]=>$a[2][3],
                $a[0][4]=>$a[2][4],
        },
        {
                $a[0][0]=>$a[3][0],
                $a[0][1]=>$a[3][1],
                $a[0][2]=>$a[3][2],
                $a[0][3]=>$a[3][3],
                $a[0][4]=>$a[3][4],
        },      
];
这部分是问题点。。当数据量增加的时候,如果还是用这个散列数组引用,那么需要在这个结构里手动增加一些数据,智能性不好了

作者: peking_A_Liang   发布时间: 2010-09-16

其中的 $hashref 是做什么用的?

作者: longbow0   发布时间: 2010-09-16

$hashref,哈希引用。

作者: peking_A_Liang   发布时间: 2010-09-16

哈希引用那部分代码意思就是在peer_conn_stat里 的第一行,是哈希的key,而下面的数据都是value,意思就是每一列的第一行是键,这列下面所有的数据都是值列表。

作者: peking_A_Liang   发布时间: 2010-09-16

有谁帮看看吗,在线等。。。

作者: peking_A_Liang   发布时间: 2010-09-16

回复 peking_A_Liang

这个可以用循环来做

作者: wfnh   发布时间: 2010-09-16

本帖最后由 longbow0 于 2010-09-16 12:36 编辑

直接用二位数组 a[x][y] 就可以解决问题,不用这么麻烦。

如果是想用第1行的值作为 key 访问,可以
  1. $rh_col = {
  2.     a[0][0] => 0,   
  3.     a[0][1] => 1,
  4.     ...
  5. }
复制代码
引用时
  1. $a[3][ $rh_col->{ $a[0][0]} ]
复制代码
这种情况,感觉用 数据库 做应该更加容易一些。

作者: longbow0   发布时间: 2010-09-16

楼上的朋友,好像你上面写的有问题,如果不用二位数组,用哈希怎么构建个数据结构出来。。以第一行为键,下面的是值。
就类似这样
my %hash_1;
my %hash_2;
foreach $key1(keys %hash1){
        foreach $key2(keys %hash2)
       {
              .....
       }
}
这种嵌套的哈希,可以实现否?主要是通过练习增强下perl的水平,刚学会简单使用perl,一周看了perl语言入门,加课后习题。

作者: peking_A_Liang   发布时间: 2010-09-16

另外,精灵王朋友,可否给个你的代码参考下,谢谢。

作者: peking_A_Liang   发布时间: 2010-09-16

#!/usr/bin/env perl
use strict;
use warnings;
$"=",";

if(@ARGV < 1) {
    die "Usage: $0 [Filename]\n";
}
my $file = $ARGV[0];
open FH,"<",$file or die "Can't open $file: $!\n";
my (@a,$b,%hash);
while (<FH>) {
    chomp;
    @a=split (/\s+/);
    $b=shift @a;
    $hash{$b}=[@a];
}
foreach (keys %hash ) {
    print "$_=>[@{$hash{$_}}]\n";
}

[oracle@imeg02 zgw]$ ./a.pl peer_conn_stat
6=>[7,8,9,10]
1=>[2,3,4,5]
a=>[b,c,d,e]
1.0.0.22=>[m,n,p,q]

是不是这样来存储数据?

作者: 99超人   发布时间: 2010-09-16

稍等,我试下。。

作者: peking_A_Liang   发布时间: 2010-09-16

不对呀,朋友,是这样a b c d e这行是键,就类似你在linux下的/proc目录下很多文件中,第一行的标题一样。。。
然后
其实就是a=>[1,6,1.0.0.22]
b=>[2,7,m]
c=>[3,8,n]
d=>[4,9,p]
e=>[5,10,q]

明白了吧。。

作者: peking_A_Liang   发布时间: 2010-09-16

回复 peking_A_Liang
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. if(@ARGV < 1)
  5. {
  6.         die "Usage: $0 [Filename]\n";
  7. }
  8. my $file = $ARGV[0];
  9. open FH,"<",$file or die "Can't open $file: $!\n";
  10. my @keys;
  11. my @temp;
  12. my $row = 0;
  13. my $hashref;
  14. while(<FH>)
  15. {
  16.         my @temp = split;
  17.         if($row == 0){
  18.             @keys = @temp;
  19.         }else{
  20.             my %temp_hash;
  21.             for(my $i = 0;$i< scalar @keys;$i ++){
  22.                 $temp_hash{$keys[$i]} = $temp[$i];
  23.             }
  24.             push @$hashref,{%temp_hash};
  25.         }
  26.         $row++;
  27. }
  28. close(FH);
  29. print "$hashref->[1]->{$keys[0]}\n";
复制代码
这个,试试

作者: 珞水的大叔   发布时间: 2010-09-16