基于perl中的一列合并多个文本文件

时间:2013-03-25 06:07:10

标签: perl csv merge

我是Perl的新手,这是我在这个博客中的第一个问题,希望能够解决。

我在文件夹中有一些文本(10-18)文件,我想要读取所有文件并合并所有文件,这些文件在Names列中具有公共变量以及所有文件的Area列。 例如 : file 1.txt

名称sim区域Cas
aa 12 54 222
ab 23 2 343
aaa 32 34 34
bba 54 76 65

file 2.txt

名称Sim Area Cas
ab 45 45 56
abc 76 87 98
bba 54 87 87
aaa 33 43 54

file 3.txt

命名Sim Area Cas

aaa 43 54 65
ab 544 76 87
ac 54 65 76

输出应为

名称Area1 Area2 area3
aaa 32 43 54
ab 23 45 76

任何人都可以帮忙解决这个问题。我是Perl的新手并且正在努力使用Hashes。

到目前为止我已尝试过这个

use strict;
use warnings;

my $input_dir = 'C:/Users/Desktop/mr/';
my $output_dir = 'C:/Users/Desktop/test_output/';

opendir SD, $input_dir || die 'cannot open the input directory $!';
my @files_list = readdir(SD);
closedir(SD);

    foreach my $each_file(@files_list)
    {
        if ($each_file!~/^\./)               
        {
            #print "$each_file\n"; exit;
            open (IN, $input_dir.$each_file) || die 'cannot open the inputfile $!';
            open (OUT, ">$output_dir$each_file") || die 'cannot open the outputfile $!';

        print OUT "Name\tArea\n"; 

            my %hash; my %area; my %remaning_data;

            while(my $line=<IN>){
            chomp $line;


            my @line_split=split(/\t/,$line);
            # print $_,"\n" foreach(@line_split);

            my $name=$line_split[0]; 
             my $area=$line_split[1]; 
                }
            }   
        }

任何人都可以提供有关如何完成此操作的指导吗? 提前谢谢。

2 个答案:

答案 0 :(得分:2)

perl -lane '$X{$F[0]}.=" $F[2]";END{foreach(keys %X){if(scalar(split / /,$X{$_})==4){print $_,$X{$_}}}}' file1 file2 file3

测试:

> perl -lane '$X{$F[0]}.=" $F[2]";END{foreach(keys %X){if(scalar(split / /,$X{$_})==4){print $_,$X{$_}}}}' file1 file2 file3
ab 2 45 76
aaa 34 43 54

答案 1 :(得分:0)

#!/usr/bin/perl

use strict;
use warnings;

my $inputDir = '/tmp/input';
my $outputDir = '/tmp/out';

opendir my $readdir, $inputDir || die 'cannot open the input directory $!';
my @files_list = readdir($readdir);
closedir($readdir);

my %areas;
foreach my $file (@files_list) {
    next if $file =~ /^\.+$/; # skip ..
    open (my $fh, "<$inputDir/$file");
    while (my $s = <$fh>) {
        if ($s =~ /(\w+)\s+[\d\.]+\s+([\d\.]+)/) {
            my ($name,$area) = ($1, $2); # parse name and area
            push(@{$areas{$name}}, $area); # add area to the hash of arrays
        }
    }
    close ($fh);
}

open (my $out, ">$outputDir/outfile");
foreach my $key (keys %areas) {
    print $out "$key ";
    print $out join " ", @{$areas{$key}};
    print $out "\n";
}
close ($out);