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

Long time parishioner, finally have a problem that my skills don't have, and a search did not provide a solution... You guys are great... Thanks for the anonymous help.

Have a great many text files... All of which have the pesky ^M for EOL, nothing I can do about that (files are created by an outside program).

I need to search each file, find a match, and replace a word that is two lines below.

Example of text:
__TypeOfAirframe__2_0_Cessna152^M
__StartAltitude__2_0_1200^M
__GearStatus__2_0_Down^M

I want to toggle the gear on all Cessna152s.

For clarity... I used _ as space markers. Imagine the above block is repeated 30 or more times, in hundreds of files. TypeOfAirframe is not always a Cessna, so I don't want to toggle the gear on my 747.

I have had great luck with

perl -pi -e 's/find/replace/g' *.txt

But, I cannot get it to recognize the ^M and spaces to perform a search on the above phrase. HELP?

Replies are listed 'Best First'.
Re: Find Replace
by kennethk (Abbot) on Dec 15, 2011 at 17:00 UTC
    ^M is a carriage return, represented by \015 or "\r" (less reliably). See Newlines in perlport. You could drop those easily with s/\r//g, but for the sake of argument I will assume you want to keep them. They are white space characters, so you can maintain insensitivity to them by ignoring trailing white space, e.g. /Cessna\d+\s*$/.

    So you could do this in a one-liner like perl -pi -e '$i--;$i=2 if /Cessna\d+\s*$/;s/Down(?=\s*$)/Up/g if !$i' *.txt

      Perfect. The one liner did just the thing

      Exactly what I needed it to do... But couldn't get the syntax.
      Thank you so much!

        Nuts - unpost.

        Seems I was able to make it work perfectly on a Unix system at the house with a file I made up to resemble the working version. At work on RH Linux - it does not work - as entered as a one line blurp from a command line - it will change all DOWNS to UP. Regardless of the aircraft type.

        I am reluctant to remove the ^M EOL, only because I have no control over the programs that are reading the files. Back to the drawing board -- thanks again for all the help - if anyone has another suggestion, I'm ready for it!

        Rob
      Thanks for the link... Very helpful for me. Still getting my butt kicked on the original post, but the link proves good reading.
Re: Find Replace
by Anonymous Monk on Dec 15, 2011 at 16:47 UTC

    But, I cannot get it to recognize the ^M and spaces to perform a search on the above phrase. HELP?

    You can change the meaning of EOL

    perl -l015 -e " s/// " tells perl to use ^M as EOL

    $ perl -le " printf q[CR \r is %03o], ord qq[\r] " CR \r is 015
      Excuse my ignorance, but will that be a temporary change? Thanks for the tip...

        Excuse my ignorance, but will that be a temporary change? Thanks for the tip...

        No, your bank account will be emptied permanently!

         

        :D

        It is a pair of global variables, perlvar#$\ and perlvar#$/