2012-07-05 10 views
5

tengo varios archivos de texto. He escrito código para ingresar 2 archivos a través del shell y fusionarlos. Pero ¿cómo fusiono varios archivos? Es un comando del sistema útil para este propósito.código de perl para fusionar varios archivos de texto

my @a = read_file($file1) 
    or die "couldn't read $file1 - $!"; 
my @b = read_file($file2) 
    or die "couldn't read $file2 - $!"; 

my $combined = {}; # hashref 

my $i=0; 
foreach (@a) { 
    chomp; 
    $combined->{$i}{b} = '' unless defined $combined->{$i}{b}; 
    $combined->{$i++}{a} = $_; 
} 

$i=0; 
foreach (@b) { 
    chomp; 
    $combined->{$i}{a} = '' unless defined $combined->{$i}{a}; 
    $combined->{$i++}{b} = $_; 
} 

foreach my $i (sort {$a<=>$b} keys %$combined) { 
    print $combined->{$i}{a}, ("\t" x 2), $combined->{$i}{b}, "\n"; 
} 

Respuesta

4

Según tengo entendido, se puede leer una línea al mismo tiempo para ambos archivos e imprimir cada línea separada con pestañas, como:

use warnings; 
use strict; 

die unless @ARGV == 2; 

open my $fha, q|<|, $ARGV[0] or die; 
open my $fhb, q|<|, $ARGV[1] or die; 

while (my $a = <$fha>, my $b = <$fhb>) { 
    chomp($a, $b); 
    printf qq|%s\t\t%s\n|, $a, $b; 
} 

Este script no funcionará si los archivos tienen diferentes número de líneas. Necesitarás otro enfoque para esa situación.

2

Puede hacerlo simplemente con cáscara: cat file1.txt file2.txt file3.txt > selected.txt

O en Perl:

use strict; 

@ARGV = ('file1.txt', 'file2.txt', 'file3.txt'); 

open MULTI, '>', 'selected.txt' 
    or die $!; 

while (<>) { 
    print MULTI; 
} 
+2

Esto no fusiona los archivos de la manera que el OP quería, los concatena. – TLP

2

¿Qué tal:

#!/usr/bin/perl 
use strict; 
use warnings; 

my @files = qw(file1 file2 file3 file4); 
my %content; 
my $max_rec = 0; 

foreach (@files) { 
    open my $fh, '<', $_ or die $!; 
    @{$content{$_}} = <$fh>; 
    chomp @{$content{$_}}; 
    close $fh; 
    $max_rec = @{$content{$_}} if scalar(@{$content{$_}}) > $max_rec; 
} 

open my $fh, '>', 'outfile' or die $!; 
for my $i (0 .. $max_rec) { 
    my $out = ''; 
    foreach (@files) { 
     $out .= defined($content{$_}[$i]) ? $content{$_}[$i] : ''; 
     $out .= "\t\t" unless $_ eq $files[-1]; 
    } 
    print $fh $out,"\n"; 
} 

archivos de entrada:

$ cat file1 
1.1 
$ cat file2 
2.1 
2.2 
$ cat file3 
3.1 
3.2 
3.3 
$ cat file4 
4.1 
4.2 
4.3 
4.4 

archivo de salida:

$ cat outfile 
1.1  2.1  3.1  4.1 
     2.2  3.2  4.2 
       3.3  4.3 
         4.4 
0

Este enfoque secuencia de comandos en un alto rendimiento con IO :: File, y sólo funciona para los archivos con al menos un texto no-blanco en la misma línea.

#!/usr/bin/perl 
use IO::File; 
@f= map { IO::File->new($_) } @ARGV; 
print $q,qq(\n) until ($q=join (qq(\t), map { m{(.*)} && $1 } map { $_->getline } @f))=~m{^\t+$} 
Cuestiones relacionadas