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

I'm not sure if someone had posted something that separate the set of line of text and save to it's respective file.

My next step is: everytime I see same city name like Miami. I would have to grab this chunk of lines and move this to miami.txt

I can search by patterns but it looks like that won't be enough since I need the whole chunk until another header comes up.
FLORIDA Inventory Report CITY: Orlando Page1 111 Item1 $1000 222 Item2 $2000 449 Item3 $9999 FLORIDA Inventory Report CITY: Miami Page2 349 Item1 $3050 224 Item2 $2340 982 Item3 $9029 FLORIDA Inventory Report CITY: Miami Page2 349 Item1 $3050 224 Item2 $2340 982 Item3 $9029

Replies are listed 'Best First'.
Re: separating every set of textline
by punkish (Priest) on Mar 02, 2005 at 04:28 UTC
    Here is a simple approach--

    1. Set a flag everytime a header starts.
    2. Grab everything for that chunk and write it to its city's file.txt.
    3. Reset the flag when the next header is encountered
    --
    when small people start casting long shadows, it is time to go to bed
Re: separating every set of textline
by davidj (Priest) on Mar 02, 2005 at 05:55 UTC
    Note that what follows is pretty much a hack, but it might get you started. What it does is
    1) grab everything from the line containing the string CITY to the line containing the string FLORIDA (I am assuming that FLORIDA is a header).
    2) grabs the first word after CITY and opens it as a text file
    3) writes all the lines grabbed as indicated above and prints them to the file.

    #!/usr/bin/perl use strict; my ($file); open(FILE, "<file.txt"); while(<FILE>) { chomp($_); if(/CITY/ ... /FLORIDA/) { if( ($file) = $_ =~ m/.+CITY:\s+(\w+)\s+/ ) { close(FH); $file .= '.txt'; open(FH, ">>$file"); } print FH "$_\n" unless $_ =~ m/FLORIDA/; } } close(FILE);
    hope this helps,
    davidj
      Only note that if the file is big, and there is not a lot of different files to create, calling open everytime a file must be update can be a considerable overhead (I've been in the same situation just a few days before).

      If the different files can be determinated before the loop, you can open all of them and the use the apropiate (i.e., keeping them in a hash). When they're not known until runtime (it was my case), I used a closure returning lexical filehandles from a hash. Something like that:

      { my %handles; # Closure keeps the hash between function calls sub handle{ my $city = shift; my $temp; unless ($handles{$city}){ open $temp, ">", "$city.txt" or die "$!"; $handles{$city} = $temp; } return $handles{$city}; } }

      It worked for me and reduced the execution time about a 50%. Hope it helps.

Re: separating every set of textline
by Roy Johnson (Monsignor) on Mar 02, 2005 at 05:14 UTC
    When you see a header, redirect your output appropriately. For lines that aren't headers, simply print them.

    Caution: Contents may have been coded under pressure.
Re: separating every set of textline
by rupesh (Hermit) on Mar 02, 2005 at 12:01 UTC

    Use $/. Very simple.

    Cheers,
    Rupesh.