Re: reading files to different output files.
by choroba (Cardinal) on May 28, 2017 at 11:32 UTC
|
Use an array of output file handles. You can use an array of input file handles, too.
Note that
print $file_handles[$i] $line;
doesn't work, you need to use curlies:
print {$file_handles[$i]} $line;
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
|
use IO::File;
my @fh;
my @file_names = ("output1.txt", "output2.txt", "output3.txt");
for (my $i=0; $i<=$#file_names; $i++){
$fh[$i]= IO::File->new( ">$file_names[$i]" ) || die "Cannot open $
+file_names[$i]: $!.\n";
}
| [reply] [d/l] |
|
my @fhs = map { open my $FH, '<', $_ or die $!; $FH } @filenames;
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
|
| [reply] |
|
|
|
|
#! /usr/bin/perl
use strict;
use warnings;
use IO::File;
my @fh;
my @file_names = ("output1.txt", "output2.txt", "output3.txt");
while ( <> ){
for (my $i=0; $i<=$#file_names; $i++){
$fh[$i]= IO::File->new( ">$file_names[$i]" ) || die "Cannot op
+en $file_names[$i]: $!.\n";
print {$fh[$i]} "$_";
}
}
print "done.\n";
It produced three output files, each containing the command that i entered in the command line. What's missing? | [reply] [d/l] |
|
| [reply] |
|
|
Re: reading files to different output files.
by shmem (Chancellor) on May 28, 2017 at 14:23 UTC
|
If you use the special null filehandle for reading multiple files on the command line (i.e. if you read via <>) , the name of the current input file will show up in the special variable $ARGV (see perlvar). You can use this variable to determine whether the file name has changed because the next file has been opened, and (re-)open the output filehandle to another file. Of course you have to provide means to change the output file name (e.g. a prefix or suffix applied to the input file name, or a counter), otherwise the same file will be re-opened and clobbered.
Example:
my $filename; # used to remember the current file name
my $out = "output"; # prefix for output files
my $ofh; # output filehandle, currently closed
while (<>) {
if ($ARGV ne $filename) {
$filename = $ARGV;
open $ofh, '>', "$out-$filename"
or die "Can't write to '$out-$filename': $!\n";
}
print $ofh $_;
}
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
| [reply] [d/l] [select] |
|
my @fh;
my @file_names = ("output1.txt", "output2.txt", "output3.txt");
my @in = <>;
my $i = 0;
open (READ, @in) || die "cannot open @in: $!.\n";
while ( <> ){
for (my $i=0; $i<=$#file_names; $i++){
$fh[$i]= IO::File->new( ">$file_names[$i]" ) || die "Cannot op
+en $file_names[$i]: $!.\n";
print {$fh[$i]} "$_";
}
}
close (READ);
print "done.\n";
by now it feels like I'm mentally retarded :( | [reply] [d/l] |
|
To expand a bit on the correct diagnosis of Anonymous Monk, you are opening the files, but you are not reading from them.
You are trying to read STDIN twice, once here:
my @in = <>;
and once here:
while ( <> ){
...
}
It's not clear to me what that is supposed to achieve.
Then you try to open a filehandle to a list:
open (READ, @in) || die "cannot open @in: $!.\n";
This suggests that you only have a single filename in @in, and that filename does not have a newline appended.
Your program logic alltogether is a bit weird, because in your while loop, you recreate your output files on every pass through the loop. This is most likely not what you want:
while ( <> ){
for (my $i=0; $i<=$#file_names; $i++){
...
}
}
Let me suggest a different structure of your program:
- Open the output file(s)
- For each input file
- Open the input file
- Read one line from the input file
- Write the line to the output file(s)
- Repeat reading
You have many parts of that already, but your program isn't structured in the right order. | [reply] [d/l] [select] |
|
|
|
|
|
| [reply] |
|
| [reply] |
|
| [reply] |