读取多行并合并为单行

时间:2013-12-02 04:20:45

标签: perl file-processing

我想以这样的方式处理文件:从多行读取并创建一个新文件,该文件将有一行对应于此。

例如: 输入文件:

12345   1   -   -   -

12346   -   2   -   4

12347   -   -   3   -

12348   5   -   -   -

12349   -   6   -   8

12350   -   -   7   -

输出文件:

12346   1   2   3   4

12349   5   6   7   8

用3行代表完整的一行。

如何在perl中执行此操作?

4 个答案:

答案 0 :(得分:2)

通过3个简单步骤完成:

  1. 创建一个哈希,将第一个单词保留为键。

  2. 从文件中读取并将输入保存在数组中。

  3. 针对每个键将元素打印到新文件。

答案 1 :(得分:1)

perl -lane'
  $r = $. % 3;
  $f = $F[0] if $r==2; 
  $arr[$_] += $F[$_] for 1 .. $#F;
  if (!$r) { print "$f @arr"; @arr=() }
' file

输出

12346  1 2 3 4
12349  5 6 7 8

答案 2 :(得分:0)

这是我的解决方案。输入和输出文件是命令行的第1和第2个参数:

#!/usr/bin/perl

use warnings;
use strict;

open(DATA, "<", $ARGV[0]) or die $!;
open(OUTPUT, ">", $ARGV[1]) or die $!;

my $count = 0;
my $id = 0;
my @arr;

foreach (<DATA>){
    chomp;
    my @data;
    # if line is not empty
    if($_ ne ""){
        @data = split(" ", $_);
        $id = $data[0];

        # merge data
        for(my $i = 1; $i <= $#data; $i++){
            if($data[$i] ne "-"){
                $arr[$i] = $data[$i];
            }
        }

        $count++;
        if ($count == 2){
            $arr[0] = $id;
        } elsif ($count == 3){
            # reset countable variable
            $count = 0;
            # print output
            print OUTPUT join " ",@arr,"\n";
        }
    }
}
close(DATA);
close(OUTPUT);

答案 3 :(得分:0)

我认为这会对你有所帮助,如果有任何澄清让我知道:

输入文件是:

12345|1|-|-|-
12346|-|2|-|4
12347|-|-|3|-
12348|5|-|-|-
12349|-|6|-|8
12350|-|-|7|-

脚本

use strict;
use warnings;
sub processor{
(my @tmp )=@_;
        my @inner;
        shift(@tmp);
            foreach my $element(@tmp){
                $_=$element;
                if((m/[0-9]/)){
                    push(@inner,$element);
                }
            }
return @inner;
}
open(INFILE,"infile.dat") or die "$!";
open(OFILE,">outfile.dat") or die "$!";
my @ecollector;
my $keyVal;
my $counter;
while(<INFILE>){
        chomp($_);
        my @tmp=split('\|',$_);
        if(($. % 3) ne 0){
            if(($. % 3) eq 2){ $keyVal=$tmp[0];}
            push(@ecollector,processor(@tmp));
        }
        else{
            push(@ecollector,processor(@tmp));
            print OFILE "$keyVal\t".join("\t",sort(@ecollector))."\n";
            @ecollector=();
        }   
}
close(INFILE);
close(OFILE);