kamadevin 发表于 2015-07-08 14:02

编程在线求助~

本帖最后由 kamadevin 于 2015-07-08 14:28 编辑

perl求助

现在需要处理几个文件
想要达到如下效果
文件格式如下

文件1
a 1
b 2
c 3
d 4
e 5

文件2
a 6
b 7
d 8
e 9
f 10

想整合在一起成为
a 1 6
b 2 7
c 3 0
d 4 8
e 5 9
f 0 10

中间以 table符分开
请问如何做到,求帮忙~

xiaoxingan99 发表于 2015-07-08 16:57

本帖最后由 xiaoxingan99 于 2015-07-08 16:59 编辑

实在不会用hash,参考以前的帖子,给出一个我写的复杂程序
open FF, "e:/perl/A.txt";
while(<FF>){
chomp;
my ($key, $value) = split / /;
$h{$key}=$value;

}

open FF1, "e:/perl/B.txt";
while(<FF1>){
chomp;
my ($key1, $value1) = split / /;
$h1{$key1}=$value1;

}
foreach $a ("a".."f"){
        unless ($h{$a}){
                $h{$a}=0;
                }
                        unless ($h1{$a}){
                $h1{$a}=0;
                        }
                                print "$a\t$h{$a}\t$h1{$a}\n";
        }

songyc_2015 发表于 2015-07-08 23:41

回复 1# kamadevin #!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

my %hash;

open my $FHA, "$ARGV";
while (<$FHA>)
{
        chomp;
        /(\S+)\s+(\S+)/;
        $hash{$1} = $2;
}
close $FHA;

open my $FHB, "$ARGV";
while (<$FHB>)
{
        chomp;
        /(\S+)\s+(\S+)/;
        $hash{$1} = length($hash{$1}) ? $hash{$1}."\t".$2: "0\t".$2;
}
close $FHB;

for (sort { $a cmp $b } keys %hash)
{
        $hash{$_} = $hash{$_} . "\t0" if (scalar split(/\t/, $hash{$_})) == 1;
        print "$_\t$hash{$_}\n";
}

jason680 发表于 2015-07-09 00:07

本帖最后由 jason680 于 2015-07-09 00:07 编辑

回复 1# kamadevin

$ perl combin.pl f1 f2
a 1 6
b 2 7
c 3 0
d 4 8
e 5 9
f 0 10

$ cat combin.pl
#! /usr/bin/env perl
use strict;
use warnings;

message() if(@ARGV < 1);

sub message{
print<<EOF;
Usage: $0 file1 ]
Ex:    $0 f1 f2
EOF
exit(1);
}
my $sCnt = 0;
my %hKey;
my @aKey;
foreach my $sFile (@ARGV){
$sCnt++;
open(FHin, "<$sFile") or die "can't open $sFile\n";
while(<FHin>){
    my($sKey, $sVal) = split;
    if(! exists $hKey{$sKey}){
      push @aKey, $sKey;
    }
    $hKey{$sKey}[$sCnt] = $sVal;
}
close(FHin);
}
foreach my $sKey (@aKey){
my $sOut = "";
foreach( 1 .. $sCnt){
    $hKey{$sKey}[$_] += 0;
    $sOut .= " $hKey{$sKey}[$_]";
}
print "$sKey$sOut\n";
}

   

MMMIX 发表于 2015-07-09 00:11

回复 4# jason680


    一个 hash 足矣:
use v5.10;

my %record;
for my $idx (0..$#ARGV) {
      open(my $h, "<", "$ARGV[$idx]")
                or die "Cannot open $ARGV[$idx]: $!";
      while (<$h>) {
                chomp;
                my @r = split / /, $_, 2;
                $record{$r}->[$idx] = $r;
      }
}

for my $k (sort keys %record) {
        $#{$record{$k}} = $#ARGV;
        my @v = map { $_ ? $_ : 0 } @{$record{$k}};
        say "$k, @v";
}

jason680 发表于 2015-07-09 00:58

本帖最后由 jason680 于 2015-07-09 08:04 编辑

回复 5# MMMIX

少不一定是优,多不一定是劣

$ perl -lane '
{
$f=$ARGV,$c++ if($ARGV ne $f);
($k, $v) = split;
$h{$k}[$c] = $v;
}
END{
$k=$_,print"$k @{+0}(1..$c)]}" for(sort keys %h);
}' f1 f2
a 1 6
b 2 7
c 3 0
d 4 8
e 5 9
f 0 10


   

zhlong8 发表于 2015-07-09 09:28

回复 6# jason680


    你再把这么多代码写命令行里我要报警抓你了:em45:

    你发个投票看看有几个人能完全看懂的

jason680 发表于 2015-07-09 10:15

回复 7# zhlong8

版主 你“抓"错人了...(我都说了:少不一定是优,多不一定是劣)

你发一篇 教教大家如何正确编程Perl...

   

zhlong8 发表于 2015-07-09 12:24

回复 8# jason680


    不排版就把没用的空格和换行删掉:mrgreen:perl -lane '$f=$ARGV,$c++if$ARGV ne$f;$h{$F}[$c]=$F}{$"="\t";$k=$_,print"$k\t@{+0}1..$c]}"for sort keys%h' f1 f2

sunzhiguolu 发表于 2016-09-13 15:22

perl -anle '{($k,$v)=@F;if(@ARGV){$h{$k}=[$v];next}if($h{$k}){$h{$k}->=$v}else{$h{$k}=}}END{print join (" ", $_, $h{$_}->, ($h{$_}-> // 0)) for sort keys %h}' a b
页: [1]
查看完整版本: 编程在线求助~