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

Suppose I have a text file like this:
XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXaaaa abcdefghijklm%nopqrstuvw%xyz
What I need to do is read the file until I reach the "aaaa" at the end of the line and then change the $/ to be % instead of \n. I tried this:
while (<FILE>) { if (/aaaa$/) { $/ = '%'; while (<FILE>) {} # I tried it with and without this loop } }
If the second while is in there, nothing happens inside of it, and without it, the loop does not cycle back again. Any suggestions?

Replies are listed 'Best First'.
Re: Changing $/ mid-file
by mirod (Canon) on Jan 17, 2001 at 04:33 UTC

    It should work. The following code works fine:

    #!/usr/bin/perl -w use strict; while (<DATA>) { if (/aaaa$/) { local $/ = '%'; # use local here for extra-cleanness ($/ is + restored to its previous state when you exit the block) while (<DATA>) { print "read: $_\n"; } } } __DATA__ XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXaaaa abcdefghijklm%nopqrstuvw%xyz

    The problem must be somewhere else in your code.

    This is actually one of my favorite tricks, it always impresses people who don't know it ;--)

Re: Changing $/ mid-file
by eg (Friar) on Jan 17, 2001 at 04:35 UTC

    If you take out the second while, it looks fine to me. Try this:

    while (<DATA>) { chomp; print "-$_-\n"; if (/aaaa$/) { $/ = '%'; } } __END__ XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXaaaa abcdefghijklm%nopqrstuvw%xyz
Re: Changing $/ mid-file
by I0 (Priest) on Jan 17, 2001 at 06:37 UTC
    {local $/ = "aaaa\n"; <FILE> } {local $/ = "%"; while( <FILE> ){ } }
      There's no need to localize $/ twice, if you combine your code into a single block:
      { local $/ = "aaaa\n"; <FILE>; $/ = '%'; while( <FILE> ) { #do something here } }
Re: Changing $/ mid-file
by Coyote (Deacon) on Jan 17, 2001 at 04:36 UTC
    Check out the local function.

    ----
    Coyote

Re: Changing $/ mid-file
by Anonymous Monk on Jan 17, 2001 at 10:00 UTC
    All these answers are extremely fine, but why doesn't the original program work? Where are the Really Great Minds ?

      What all solutions above at least implicitly discussed was the need to preserve $/ for the next round in the outer while{} loop. That's why all solutions use at least one local statement to keep the old value of $/.

      You should take some time to study the solutions and next time maybe be more explicit at what dosen't work with your program, as the program works almost well (except for one warning on undefinded data). I guess a more representative dataset would have been

      XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXaaaa abcdefghijklm%nopqrstuvw%xyz XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXaaaa abcdefghijklm%nopqrstuvw%xyz
      which dosen't work that well with your original program.