How Do I Combine Two Files in Perl?
I want to read in two input files and output a new file that contains one line that is a concatenation of each corresponding line from the two input files.
For instance:
line 1 of the new output file would have:
info from input file 1, line 1 some number of tabs info from input file 2, line 1
.
.
.
If either in开发者_开发知识库put file has more lines than the other the rest of the lines should be inserted into the output file in their correct position.
Thanks.
open FP1,"filename1";
open FP2,"filename2";
my ($l1,$l2);
while(1)
{
$l1=<FP1>; chomp $l1;
$l2=<FP2>; chomp $l2;
last unless(defined $l1 or defined $l2);
print $l1.$l2,"\n";
}
close FP2;
close FP1;
I like hashes for aggregating things. This is quick, if not particularly elegant.
#!perl
use strict;
use warnings;
my ($file1, $file2) = @ARGV;
die "usage: $0 file1 file2\n"
unless $file1 && $file2;
use File::Slurp;
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";
}
This is really no different that looping through one file as long as you pay attention to a few of Perl's tricks. For one file it is common to use
use strict;
use warnings;
use English qw(-no_match_vars);
my $filename = 'foo';
open my $file, '<', $filename or die "Failed to open '$filename' $OS_ERROR\n";
while (my $line = <$file>) {
# work with $line
}
close $file;
This can be expanded to two files by opening both and changing the loop conditional to only end when both files are done reading.
But there is a catch, when Perl sees a simple read from a file handle as the conditional for a while loop it wraps it in defined()
for you, since the conditional is now more than a simple read this needs to be done manually.
use strict;
use warnings;
use English qw(-no_match_vars);
my $filename1 = 'foo';
my $filename2 = 'bar';
open my $file1, '<', $filename1 or die "Failed to open '$filename1' $OS_ERROR\n";
open my $file2, '<', $filename2 or die "Failed to open '$filename2' $OS_ERROR\n";
my ($line1, $line2);
while ( do { $line1 = <$file1>; $line2 = <$file2>; defined($line1) || defined($line2) } ) {
# do what you need to with $line1 and $line2
}
close $file1;
close $file2;
You could first query (with a wc -l
) which file has more lines. Assuming (for the sake of pseudocode) that file 1 has more lines, then do the following:
use strict;
use warnings;
open(my $fh,"<","file 1") or die ("Couldn't open file 1: $!");
open(my $write,">","output.csv") or die ("Couldn't open output.csv: $!");
my $str;
my $count=1;
while(my $line=<$fh>)
{
$str=`head -n $count file 2 | tail -n 1`. (\tx[however many tabs you want]) . $line;
print $write $str;
$count++;
}
close($fh);
close($write);
#!/usr/bin/env perl
#merging 3 - lines of first file and 3 lines of second file and next of these.
open(F1, "<file1") or die "\ncould not find your file1\n";
my@lines1;@lines1 = < F1 > ;
close(F1);
open(F2, "<file2") or die "\ncould not find your file2\n";
my@lines2;@lines2 = < F2 > ;
close(F2);
my $value;
my $nums;
print "\nplease write your output file name::::\n";
chomp($file = < STDIN > );
open(F3, "> $file") or die "\n could not write into your file\n";
$value = 0;
foreach $nums(@lines1) {
if ($value % 3 == 0) {
print F3 $lines2[$value];
print F3 $lines2[$value + 1];
print F3 $lines2[$value + 2];
}
print F3 $nums;
$value++;
}
close(F3);
精彩评论