natty_dread has asked for the wisdom of the Perl Monks concerning the following question:

I trying to take one list of machine names (let's say there's 1000 machines in that list). I want to run my script against it and parse those machine names out into seperate files of 200 machine names. I'm having problems with the logic though...here's what little code I have:

$count = 0; open (DISTLISTS, " < rdy.csv") || die "Unable host file for splitting: + $!."; foreach my $dist_split (<DISTLISTS>) chomp $dist_split; $count ++; open (OUTPUT1, " >>A.csv") print OUTPUT1 "$dist_split\n"; if ($count == 200) { } }
As just can't piece together the logic necessary to achieve this task.

Replies are listed 'Best First'.
Re: parsing lists
by RazorbladeBidet (Friar) on Mar 03, 2005 at 15:41 UTC
    Do you already have pre-determined file names in place?

    my @files = qw( A.csv B.csv C.csv D.csv E.csv );


    I guess you might want to come up with something extensible so that the list can automatically expand.

    The $count variable is really unnecessary here. You could use $. (unless there are criteria where you might skip lines)

    You probably don't want to open the OUTPUT every line. So... (psuedo-untested-code to give you an idea)
    open( OUTPUT, $files[0] ) or die... while( <DISTLISTS> ) { if (not $. % 200) { close OUTPUT; open OUTPUT, $files[$./200] or die... } print OUTPUT, $dist_split; } close OUTPUT;


    Just an idea.
    --------------
    It's sad that a family can be torn apart by such a such a simple thing as a pack of wild dogs
Re: parsing lists
by davido (Cardinal) on Mar 03, 2005 at 15:43 UTC

    Something like this? (UNTESTED):

    my $count = 0; my $outfile = 'A'; open DISTLISTS, '<', 'rdy.csv' or die "Unable to host file for splitting: $!\n"; while my $dist_split ( <DISTLISTS> ) { if( $count % 200 == 0 ) { close OUTFILE unless $count == 0; open OUTFILE, '>', $outfile . '.csv' or die "Couldn't open output file: $!\n"; $outfile++; } print OUTFILE $dist_split; $count++; } close OUTFILE or die "Bleah! $!\n"; close DISTLISTS;

    I haven't tested this, but it should get you going down a road that will lead to a workable solution.


    Dave

Re: parsing lists
by tphyahoo (Vicar) on Mar 03, 2005 at 15:42 UTC
    1) put
    use warnings; use strict;
    at the top of your file.

    2) I think you are missing a semicolon at the end of -the "open" line.

    UPDATE: Here's some untested code...

    use warnings; use strict; $count = 0; open (DISTLISTS, " < rdy.csv") || die "Unable host file for splitting: + $!."; while (<DISTLISTS>) { chomp $dist_split; if ($. % 200 == 0) { # modular arithmetic $count ++; } my $filename = "file$count.csv"; open (OUTPUT1, " >>$filename") print OUTPUT1 "$dist_split\n"; close OUTPUT1; }
      put the open inside the if block and the close outside the while block.

      Caution: Contents may have been coded under pressure.
        Yep. Ok this is tested and works.
        use warnings; use strict; my $count = 0; my $filename = "file0.csv"; open (DISTLISTS, " < rdy.csv") || die "Unable host file for splitting: + $!."; while (<DISTLISTS>) { chomp $_; if ( ($. - 1) % 200 == 0) { # modular arithmetic $count ++; my $filename = "file$count.csv"; open (OUTPUT1, " >$filename") } print OUTPUT1 "$_\n"; if ($. % 200 == 0) { # modular arithmetic close OUTPUT1; } }
Re: parsing lists
by sh1tn (Priest) on Mar 03, 2005 at 16:31 UTC
    use strict; use File::Slurp; my $filename = shift; my @lines = read_file($filename); my $counter; for( @lines ){ ++$counter > 200 and last; s/\r?\n//; write_file("$counter-$_.cvs"); }


      If you don't want to, or are unable to install File::Slurp, it's still pretty small and painless:

      open FH, "<$filename" or die "Cannot open $filename: $!"; my @lines = <FH>; close FH;
      This creates a file for every line of input.
      write_file("$counter-$_.cvs");
      Careful!

      Also, sh1tn, I don't understand

      ++$counter > 200 and last;
      but I've seen it around... this is some kind of perl idiom right? What were you trying to do?
        Also, sh1tn, I don't understand
        ++$counter > 200 and last;
        ++$counter # increments the value of $counter and returns # the values after the increment and # logical and operator last # immediately exits the loop
        You may want to see perlop and last command.


Re: parsing lists
by jhourcle (Prior) on Mar 04, 2005 at 02:13 UTC

    Based on the code you gave, you may want to look at the unix command 'split' before you spend too much time on this, if the only requirement is that each file be 200 lines.

    If you're on a system that doesn't have it, go with the logic that RazorbladeBidet posted -- to get it from pseudocode to running, you'll want to change the print line to print OUTPUT $_; (there might be something else, as I haven't tried it either)