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

I want to split an html page, that is one chapter of notes, into 6 pages or soo. There are no images and the pages will be only $X_Lines long. I'm sick right now and I have no clue on how to do it.... All I know it that the script should:open the chapter notes page I want, read it, and slit it into variables...and then save each variable as a new pages...like chapterx_page_1.html (56 Lines) chapterx_page_2.html (56 Lines) chapterx_page_3.html (33 Lines)<-- Left over lines END:) I don't know how to split the page by counting the lines and I also don't know how to save new pages from variables.
  • Comment on How do I split a file by lines into smaller files

Replies are listed 'Best First'.
Re: How do I split a file by lines into smaller files
by chromatic (Archbishop) on Mar 06, 2001 at 06:00 UTC
    If you read all lines into an array, you can use a list slice or splice to pull out chunks of text:
    open(INFILE, $filename) or die "Can't open $filename: $!"; my @lines = <INFILE>; my @chapters; $chapters[1] = @lines[0 .. 55]; $chapters[2] = @lines[56 .. 112];
    There are more idiomatic ways to do that, but it'll get you started.

    Update: merlyn's right. That's what happens when you switch approaches while typing out your code. If you don't want to use references, do instead:

    @chapter1 = @lines[0 .. 55]; @chapter2 = @lines[56 .. 112];
    In general, I'd discourage that approach, because appending numbers to variable names is a warning sign. In this case, it's not a big deal.
      $chapters[1] = @lines[0 .. 55]; $chapters[2] = @lines[56 .. 112];
      Ooops... you're slipping. You need an extra anon-array constructor there:
      $chapters[1] = [@lines[0 .. 55]]; $chapters[2] = [@lines[56 .. 112]];

      -- Randal L. Schwartz, Perl hacker

      Seems pretty straightforward:
      open (INFILE,$filename) or die "a slow, suffocating death: $!"; $segment=1; ENDLESS: while (1) { open (OUTFILE,">".$filename.$segment.$extension); foreach (1..56) { $line=<INFILE> or end ENDLESS; print OUTFILE $line; } close OUTFILE; $segment++; }
      The variable names should be pretty self-explanatory. Hope that helps, Brother Ade
Re: How do I split a file by lines into smaller files
by swr (Initiate) on Mar 06, 2001 at 09:20 UTC
    Here is my contribution...
    $lines = 56; $filename = 'chapterx.html'; $nameformat = 'chapterx_page_%d.html'; open(INFILE, "<$filename") or die $!; while(<INFILE>) { if ($. % $lines == 1) { open(OUTFILE, '>'.sprintf($nameformat, $. / $lines + 1)) or di +e $!; } print OUTFILE $_; }
(dkubb) Re: (2) How do I split a file by lines into smaller files
by dkubb (Deacon) on Mar 07, 2001 at 12:58 UTC

    Here's another way to split one large HTML page down into smaller 56-line pages:

    #!/usr/bin/perl -w use strict; use constant CHAPTER_LENGTH => 56; open INFILE, "< $ARGV[0]" or die "Could not open file $ARGV[0]: $!"; my $page = 1; until(eof INFILE) { open OUTFILE, "> chapterx_page_$page.html" or die "Could not open file chapter_$page: $!"; while(<INFILE>) { print OUTFILE; last unless $. % CHAPTER_LENGTH; #will return true when the line #no. is equally divisible by 56 } ++$page; }

    This will iterate over each line in <INFILE>, and on every 56th line, it will start a new chapter. The last chapter will be 56 lines or less.

    If your file size ever gets large I would suggest using this method. Reading a large file into an array, then slicing the aray after, will be more expensive than iterating over the source file one line at a time.