免费注册 查看新帖 |

Chinaunix

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

Perl hash多重键值 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-11-06 06:48 |只看该作者 |倒序浏览
数据:

1|2|4|6
4|2|1
4|5|7|1|3|5|2
。。。。
这样的文本,处理成没有重复的数字对。
例如:
1|2|4|6   生成数字对儿,应该如下
1  2            
2  4
4  6
4|2|1  生成数字对儿,应该如下
4  2
2  1(根据左小右大的规则变为2  4;1  2)
4|5|7|1|3|5|2  生成数字对儿,应该如下
4  5
5  7
7  1
1  3
3  5
5  2(根据左小右大的规则变为4  5;5  7;1  7;1  3;3  5;2  5)

最终生成文本:
1  2
1  3
1  7
2  4
2  5
3  5
4  5
5  7



我想把这些数字对儿当成键值key,加入到hash中,每重复一次,value加1;应该怎么做?谢谢啦
%link;
$link{$num1}{$num2}=1; 我想写成这个样子的,但刚开始学perl对,很多语法不熟,例如
如何将这些数字对输入到键值里 ,如何表示这些键值eg{$num1}{$num2}

walklan 该用户已被删除
2 [报告]
发表于 2014-11-06 09:03 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
3 [报告]
发表于 2014-11-06 14:01 |只看该作者
本帖最后由 pitonas 于 2014-11-06 07:57 编辑

if | => /|/, if | => /\|/
15 行:
    print "$k\t$_\n" for sort { $a <=> $b } keys %{ $link{$k} };
  1. #!/usr/bin/perl

  2. my %link;
  3. while (<DATA>) {
  4.     chomp;
  5.     my @data = split /|/;    # HERE -> [ | ne | ]
  6.     for my $i ( 0 .. @data - 2 ) {
  7.         $data[$i] > $data[ $i + 1 ]
  8.           ? $link{ $data[ $i + 1 ] }{ $data[$i] }++
  9.           : $link{ $data[$i] }{ $data[ $i + 1 ] }++;
  10.     }
  11. }

  12. for my $k ( sort { $a <=> $b } keys %link ) {
  13.     print "$k\t$_\n" for sort keys %{ $link{$k} };
  14. }

  15. __DATA__
  16. 1|2|4|6
  17. 4|2|1
  18. 4|5|7|1|3|5|2
复制代码
回复 1# jsy1116


   

论坛徽章:
1
羊年新春福章
日期:2015-04-28 20:40:58
4 [报告]
发表于 2014-11-07 16:24 |只看该作者
没有哈希~试试
  1. #!/usr/bin/perl
  2. use strict;
  3. my @out;
  4. while (<DATA>){
  5. chomp;
  6. my @all = split /\|/,$_;
  7. push @out,[$all[$_],$all[$_+1]]  for (0..$#all-1) ;
  8. }
  9. $_ = [sort @$_] for @out;
  10. my @sort = sort {$a->[0] <=> $b->[0]}@out;
  11. my $first = shift @sort;
  12. for my $sort (@sort){
  13.   if ($sort[0] == $first[0] && $sort[1] == $first[1]){
  14.    next;
  15.   }
  16.   else {
  17.   print join "\t",sort @$first;
  18.   print "\n";
  19.   $first = $sort;
  20.   }
  21. }
  22. print join "\t",sort @$first;



  23. __DATA__
  24. 1|2|4|6
  25. 4|2|1
  26. 4|5|7|1|3|5|2
复制代码
回复 1# jsy1116


   

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
5 [报告]
发表于 2014-11-08 17:54 |只看该作者
试试 ~ {:2_168:}
  1. my @out;

  2. while (<DATA>) {
  3.     chomp;
  4.     my @all = split /\|/;
  5.     push @out, [ sort { $a <=> $b } @all[ $_, $_ + 1 ] ] for 0 .. $#all - 1;
  6. }

  7. @out = sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @out;

  8. my $last = $out[-1];

  9. for my $pair (@out) {
  10.     next if $pair->[0] == $last->[0] && $pair->[1] == $last->[1];
  11.     print join( "\t", @$pair ), "\n";
  12.     $last = $pair;
  13. }

  14. __DATA__
  15. 1|2|4|6
  16. 4|2|1
  17. 4|5|7|1|3|5|2
复制代码
回复 4# 清泉一边


   

论坛徽章:
1
羊年新春福章
日期:2015-04-28 20:40:58
6 [报告]
发表于 2014-11-09 16:25 |只看该作者
学习了!大神啊,前段时间一直学习你的代码~对我帮助很大啊 回复 5# pitonas


   

论坛徽章:
3
CU十二周年纪念徽章
日期:2013-10-24 15:41:34子鼠
日期:2013-12-14 14:57:19射手座
日期:2014-04-25 21:23:23
7 [报告]
发表于 2014-11-10 15:42 |只看该作者
回复 1# jsy1116
  1. my ($h,$n);
  2. while (<DATA>) {
  3.     my @line = split /\|/;
  4.     my $m;
  5.     $m .= $_ for @line;
  6.     $m =~ /((?:..)*?)(?{if (length $1==2){$h->{$1}++ } })(*F)/g;
  7.     for (keys %$h) {
  8.         @m=sort split //;
  9.         $n->{"@m"}++;
  10.     }
  11. }
  12. print join "\n", sort keys %$n;
  13. __DATA__
  14. 1|2|4|6
  15. 4|2|1
  16. 4|5|7|1|3|5|2
复制代码

论坛徽章:
0
8 [报告]
发表于 2014-11-11 03:26 |只看该作者
回复 3# pitonas

大神,方法很好用,但引到程序中的时候,屏幕有输出,但是没有写入文件,根本都没有生成文件,纯新手,跪请指教


#!/usr/bin/perl -w
# jsy
# $Id$

use warnings;

if(scalar(@ARGV)!=2)
{
    print STDERR "usage: path.pl \$scrpath \$dstpath\n";
    exit -1;
}

my $scrpath = $ARGV[0];
my $dstpath = $ARGV[1];
print "$scrpath\n";
print "$dstpath\n";

my @files = split /\n/, `find $scrpath -name "*.all-paths.bz2" -print`;
foreach my $file(@files)
{
   if($file =~ /(.+)\/(.+)$/)
        {
            my @filename = split /\./,$2;   #$filename[0];
            if($filename[0] =~ /^(199(\d{2})\d{2}$/)
            {
                print "$filename[0]\n";
                #open INFILE, "$file";
                open(INFILE, "bzcat $file|" || die("could not open paths file\n";
                #my $ipv4FileName = $dstpath."$filename[0].paths4";
                my $ipv4FileNamelink = $dstpath."$filename[0].paths4.link";
                my $ipv6FileNamelink = $dstpath."$filename[0].paths6.link";
                open OUTFILE4LINK, ">>ipv4FileNamelink";
                if (-e "$ipv4FileNamelink"
                {
                        `cat /dev/null > $ipv4FileNamelink`
                }
                if(-e "$ipv6FileNamelink"
                {
                        `cat /dev/null > $ipv6FileNamelink`
                }
                #######################################################################
                my %link4;
                my %link6;
                while(<INFILE>
                {
                        chomp;
                        my @lf = split;
                        my @aspath_fields = split /\|/, $lf[1];
                        my $aspath_length = scalar(@aspath_fields);
                        my $num=1;
                        if ($aspath_length >1)
                        {
                            for my $i (0..@aspath_fields-2)
                            {
                                $aspath_fields[$i]>$aspath_fields[$i+1]?$link4{$aspath_fields[$i+1]}{$aspath_fields[$i]}++link4{$aspath_fields[$i]}{$aspath_fields[$i+1]}++;
                            }
                         }
                         if ($aspath_length >1 && $lf[2] =~ /\:/)
                        {
                            for my $i (0..@aspath_fields-2)
                            {
                                $aspath_fields[$i]>$aspath_fields[$i+1]?$link6{$aspath_fields[$i+1]}{$aspath_fields[$i]}++link6{$aspath_fields[$i]}{$aspath_fields[$i+1]}++;
                            }
                         }  
                  }
                open OUTFILE6LINK, ">>ipv6FileNamelink";        
                for my $k4 ( sort{$a<=>$b} keys %link4)
                {   for my $k ( sort {$a<=>$b} keys %{$link4{$k4}} )
                    {
##########大神,这个地方在屏幕可以输出,但是写入不到这个文件里,perl新手很无语,跪请大神赐教##################################################                       
                        print "$k4\t$k\n";
                        print OUTFILE4LINK "$k4\t$k\n";
                    }     
                }
                for my $k6 ( sort{$a<=>$b} keys %link6)
                {
                    for my $k ( sort {$a<=>$b} keys %{$link6{$k6}} )
                    {
                        print "$k6\t$k\n";
                        print OUTFILE6LINK "$k6\t$k\n";
               
                    }
                }
                print "finish-$ipv4FileNamelink\n";
                close INFILE;
                close OUTFILE4LINK;
                close FD;
                close OUTFILE6LINK;
            }
       

            
        }
   
    }

论坛徽章:
0
9 [报告]
发表于 2014-11-11 03:52 |只看该作者
回复 3# pitonas


    请教大神 ,如何写入文件

论坛徽章:
1
羊年新春福章
日期:2015-04-28 20:40:58
10 [报告]
发表于 2014-11-11 14:05 |只看该作者
print 后面都应该加上OUTFILE 呀,要不他就只输在屏幕上了~回复 9# jsy1116


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP