in reply to Re: reading files to different output files.
in thread reading files to different output files.

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

Replies are listed 'Best First'.
Re^3: reading files to different output files.
by Corion (Patriarch) on May 30, 2017 at 11:08 UTC

    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?

        Where do you use @file_names ?

        foreach (@ARGV) sets $_ to the script arguments, where do you use $_ ?

        ($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,

        Do you get an error message? If so, why don't you post it?

        so what's the problem?

        The problem is that you are getting things mixed up. So several problems:

        • You loop foreach (@ARGV) and use $ARGV instead of $_ in the inner loop.
        • You assign to $out[$i], then increment $i, then access $out[$i] - which is undefined. Bummer. You need not stuff the filehandle into @out, since you are only using one output filehandle each time through. Use a lexical filehandle e.g. my $outfh = IO::File->new(...)
        • You are missing a $ in the expression ">file_names[$i]" - that should be ">$file_names[$i]". Same in the subsequent argument to <c>die.</c>

        Having fixed that:

        while (<>){

        This loop reads all files on the commandline line by line, file after file and executes the code enclosed in the loop body, for every line from all files.

        Inside the while loop, you iterate over all files again with the foreach(ARGV) inner loop, opening and reading them. You open, read, write all files over and over as many times as all the files have lines, always incrementing $i which gets you quickly past the end of @file_names.

        Drop the outer while (<>) loop.

        update: But why am I writing you, at all? You didn't give a damn at Re: reading files to different output files., so what...

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

      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++; }
Re^2: reading files to different output files.
by shmem (Chancellor) on May 30, 2017 at 11:46 UTC

    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'
Re^3: reading files to different output files.
by Anonymous Monk on May 30, 2017 at 11:10 UTC

    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.

Re^3: reading files to different output files.
by Anonymous Monk on May 30, 2017 at 10:50 UTC

    You are not reading any files.