in reply to reading files to different output files.

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'

Replies are listed 'Best First'.
Re^2: reading files to different output files.
by ic23oluk (Sexton) on May 30, 2017 at 07:40 UTC

    Okay, tried it again but it writes the names of the comman line input to the output files instead of the content of the input files. :/ Here's my code:

    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 :(

      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:

      1. Open the output file(s)
      2. For each input file
      3. Open the input file
      4. Read one line from the input file
      5. Write the line to the output file(s)
      6. Repeat reading

      You have many parts of that already, but your program isn't structured in the right order.

        first of all, thank you for your effort :) I wrote another program and I'm sure I am nearer to the solution than ever. However, it doesn't do anything:

        #! usr/bin/perl use strict; use warnings; use IO::File; my @out; my @file_names = ("output1.txt", "output2.txt", "output3.txt"); my $i = 0; while (<>){ foreach (@ARGV){ open (READ, $ARGV) || die "Cannot open $ARGV: $!.\n"; $out[$i] = IO::File->new( ">file_names[$i]" ) || die "Cannot o +pen file_names[$i]: $!.\n"; $i++; while ( <READ> ){ print {$out[$i]} "$_"; } } }

        so what's the problem?

        I finally solved it :) Thank you all, great community!

        here's my solution:
        #! usr/bin/perl use strict; use warnings; use IO::File; my @out; my @file_names = ("output1.txt", "output2.txt", "output3.txt"); my $i = 0; my $file; if ($#ARGV < 1){ die "Usage: $0 Argument1 Argument2 ... \n"; } foreach $file (@ARGV){ open (READ, $file) || die "Cannot open $file: $!.\n"; $out[$i] = IO::File->new( ">$file_names[$i]" ) || die "Cannot open + $file_names[$i]: $!.\n"; while (my $line = <READ> ){ print {$out[$i]} "$line"; } $i++; }

      Did you understand the node you've been replying to? If not, please tell.

      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

      start with changing <> into <READ> to actually read the file, and drop the module IO::File, you don't need it. Furthermore @in should probably be $in to collect userinput.

      You are not reading any files.