2012-07-05 21 views
5

tôi có nhiều tệp văn bản. Tôi đã viết mã để nhập 2 tệp thông qua trình bao và hợp nhất chúng. Nhưng làm cách nào để hợp nhất nhiều tệp. Lệnh hệ thống hữu ích trong mục đích này.mã perl để hợp nhất nhiều tệp văn bản

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"; 
} 

Trả lời

4

Như tôi hiểu, bạn có thể đọc một dòng cùng lúc cho cả tập tin và in mỗi dòng tách ra với các tab, như:

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; 
} 

Kịch bản này sẽ không hoạt động nếu file có khác nhau số dòng. Bạn sẽ cần một cách tiếp cận khác cho tình huống đó.

2

Bạn có thể làm điều đó chỉ đơn giản trong shell: cat file1.txt file2.txt file3.txt > selected.txt

Hoặc trong Perl:

use strict; 

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

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

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

Điều này không hợp nhất các tệp theo cách mà OP muốn, nó kết hợp chúng. – TLP

2

Làm thế nào về:

#!/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"; 
} 

tập tin đầu vào:

$ 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 
tập tin 363.210

đầu ra:

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

Kịch bản này tập trung vào hiệu suất cao với IO :: File, và chỉ làm việc cho các tập tin có ít nhất một số văn bản không có chỗ trống trên cùng một dòng.

#!/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+$} 
Các vấn đề liên quan