First off, use the indents, Luke. They will help.

You seem a little unclear (judging from your variable names) whether the first param is the number of lines per output file, or the number of files to generate - I'm assuming the latter.

I also note that you use two different forms of opening the input file for the proper read - and you seem to use them at the same time. I've gone with the standard, non-module, based version.

First off (and assuming that your param is number of files, not max lines), just let any surplus lines be written to your final file. I'll leave you to spot the rest of the changes (comments included)...

#!/opt/bin/perl -w use strict; # we want a valid positive integer for number of files to split the or +iginal file into my $fn_count = $ARGV[0]; die "Bad number of files\n" unless($fn_count =~ /^\d+$/ and $fn_count +> 0); main(); exit(0); sub main{ # Work out how many lines per output file - there may be some additi +onal lines in the final file # e.g. a 10-line file split into 3 files will be 3 lines for the fir +st two, then 4 in the final file # also, if the result of the div is 0, then make it 1 open(IN, $ARGV[1])||die "Cannot open $ARGV[1]:$!\n"; my $lines = 0; $lines ++ while(<IN>); close IN; my $lines_per_file = int($lines/$fn_count); $lines_per_file = 1 if !$lines_per_file; # Set the current line count to 0 # and the current output file to 1 my $ln_count = 0; my $file_number = 1; # Re-open the input file open(IN, $ARGV[1])||die "Cannot open $ARGV[1]:$!\n"; # Open our first output file (original filename + _<file_number>) open(OUT, ">$ARGV[1]_$file_number")||die "Cannot open $ARGV[1]_$file +_number for write:$!\n"; while(<IN>){ # If we've reached our total output for this file (providing it's +not the last file)... if($ln_count == $lines_per_file and $file_number < $fn_count){ $file_number ++; #...bump this up for the next file... $ln_count = 0; # ...reset line count back to 0... # ... close the current file and open the next one close OUT; open(OUT, ">$ARGV[1]_$file_number")||die "Cannot open $ARGV[1]_$ +file_number for write:$!\n"; } # print to the current output file print OUT $_; # inc our line count $ln_count ++; } # close the final file close OUT; }
Tom Melly, tom@tomandlu.co.uk

In reply to Re: Problem with multiple loops by Melly
in thread Problem with multiple loops by chinamox

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.