Perl multiline command syntax

Discussion in 'Perl Misc' started by Nigel, May 13, 2004.

  1. Nigel

    Nigel Guest

    Hello

    I am trying to use perl to find and replace in a large text file but I
    cannot seem to get it to search over multiple lines.

    # cat file.txt | perl -p - i -e
    's/pattern(.*)endofpattern/replacement/g'

    I have tried many combinations but whatever I try, I can only get it
    to search line by line. I have read everywhere about using /m but i
    dont understand where to use it.

    Can someone please help me.
     
    Nigel, May 13, 2004
    #1
    1. Advertising

  2. Nigel

    Paul Lalli Guest

    On Thu, 13 May 2004, Nigel wrote:

    > Hello
    >
    > I am trying to use perl to find and replace in a large text file but I
    > cannot seem to get it to search over multiple lines.
    >
    > # cat file.txt | perl -p - i -e
    > 's/pattern(.*)endofpattern/replacement/g'
    >
    > I have tried many combinations but whatever I try, I can only get it
    > to search line by line. I have read everywhere about using /m but i
    > dont understand where to use it.
    >
    > Can someone please help me.


    First, you need to tell Perl to read the whole file in as one string,
    rather than line by line. Otherwise, your s/// is only operating on one
    line at a time. To do this, supply the -0777 switch (see perldoc perlrun
    for more info here).

    Second, you need to tell the search-and-replace that . should match *any*
    character, including a newline. By default, . does not match newlines.
    To do this, provide the /s switch to the regexp. (The /m switch has
    nothing to do with this issue - it's used to change the $ and ^ anchors,
    which aren't used here).

    Third, why are you bothering to invoke a cat process, rather than just
    feeding the relevant file to the perl oneliner?


    perl -0777 -pi -e 's/pattern.*endofpattern/replacement/gs' file.txt

    (note that I removed the parens because $1 wasn't being used. If your
    actual replacement does use $1, add the parens back in.)

    Hope this helps,
    Paul Lalli
     
    Paul Lalli, May 13, 2004
    #2
    1. Advertising

  3. Nigel

    Todd Guest

    Nigel wrote:

    > Hello
    >
    > I am trying to use perl to find and replace in a large text file but I
    > cannot seem to get it to search over multiple lines.
    >
    > # cat file.txt | perl -p - i -e
    > 's/pattern(.*)endofpattern/replacement/g'
    >
    > I have tried many combinations but whatever I try, I can only get it
    > to search line by line. I have read everywhere about using /m but i
    > dont understand where to use it.
    >
    > Can someone please help me.

    This works for me. It makes a backup copy and fixes the file.

    perl -i.old -p -e "s/old_string/new_string/g" file.txt

    Todd
     
    Todd, May 13, 2004
    #3
  4. On Thu, 13 May 2004 11:35:54 +0930, Nigel <> wrote:
    > I am trying to use perl to find and replace in a large text file but I
    > cannot seem to get it to search over multiple lines.
    >
    > # cat file.txt | perl -p - i -e
    > 's/pattern(.*)endofpattern/replacement/g'


    I think this is explained well in the "perlrun" manpage; look at the
    documentation for the "-p" and "-0" options. (That's a zero, not an
    "oh".)

    Two more comments:
    * you want "-i", not "- i"
    * you don't need to use "cat"--you can do this (untested):

    perl -pi -0777 -e 'whatever' file.txt
     
    John J. Trammell, May 13, 2004
    #4
  5. Nigel

    Thomas Kratz Guest

    Nigel wrote:

    > Hello
    >
    > I am trying to use perl to find and replace in a large text file but I
    > cannot seem to get it to search over multiple lines.
    >
    > # cat file.txt | perl -p - i -e
    > 's/pattern(.*)endofpattern/replacement/g'
    >
    > I have tried many combinations but whatever I try, I can only get it
    > to search line by line. I have read everywhere about using /m but i
    > dont understand where to use it.


    the /m modifier won't help here because it changes the behaviour of the
    anchors ^ and $. You want /s because it lets . match a newline.

    Also your pattern will only match once because the (.*) will eat up all
    characters between the first occurence of 'pattern' and the *last*
    occurence of 'endofpattern'. You have to switch to non-greedy matching by
    putting a '?' after the quantifier.

    So try:
    's/pattern(.*?)endofpattern/replacement/sg'

    And then reread 'perldoc perlre' again, and again, .... ;-)
    You'll need more than a few rereads before you get familiar with it (I
    sure did).

    Thomas

    --
    open STDIN,"<&DATA";$=+=14;$%=50;while($_=(seek( #J~.> a>n~>>e~.......>r.
    STDIN,$:*$=+$,+$%,0),getc)){/\./&&last;/\w| /&&( #.u.t.^..oP..r.>h>a~.e..
    print,$_=$~);/~/&&++$:;/\^/&&--$:;/>/&&++$,;/</ #.>s^~h<t< ..~. ...c.^..
    &&--$,;$:%=4;$,%=23;$~=$_;++$i==1?++$,:_;}__END__#....>>e>r^..>l^...>k^..
     
    Thomas Kratz, May 13, 2004
    #5
  6. Nigel

    Paul Lalli Guest

    On Thu, 13 May 2004, Todd wrote:

    > Nigel wrote:
    >
    > > Hello
    > >
    > > I am trying to use perl to find and replace in a large text file but I
    > > cannot seem to get it to search over multiple lines.
    > >
    > > # cat file.txt | perl -p - i -e
    > > 's/pattern(.*)endofpattern/replacement/g'
    > >
    > > I have tried many combinations but whatever I try, I can only get it
    > > to search line by line. I have read everywhere about using /m but i
    > > dont understand where to use it.
    > >
    > > Can someone please help me.

    > This works for me. It makes a backup copy and fixes the file.
    >
    > perl -i.old -p -e "s/old_string/new_string/g" file.txt


    No it doesn't. At least, it doesn't do what the OP asked for. The OP was
    specifically asking about making a search-and-replace where the pattern
    spans multiple lines. Your code does not do that. See other replies in
    this thread.

    Paul Lalli
     
    Paul Lalli, May 13, 2004
    #6
  7. Nigel <> wrote:

    > I am trying to use perl to find and replace in a large text file but I
    > cannot seem to get it to search over multiple lines.



    Searching over multiple lines in not the problem.

    Getting multiple lines to search over in the first place is the problem.


    > # cat file.txt | perl -p - i -e



    -p reads only one line at a time.


    > I have tried many combinations



    Try this one:

    perldoc -q matching

    I'm having trouble matching over more than one line. What's wrong?


    > I have read everywhere about using /m but i
    > dont understand where to use it.



    Use it when you want ^ and $ to mean "begin/end of line" instead
    of meaning "begin/end of string".


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, May 13, 2004
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Brad Johnson

    Multiline command line parsing

    Brad Johnson, Sep 19, 2007, in forum: Python
    Replies:
    0
    Views:
    338
    Brad Johnson
    Sep 19, 2007
  2. lucy
    Replies:
    7
    Views:
    191
    Joe Smith
    Sep 3, 2004
  3. dale zhang
    Replies:
    8
    Views:
    437
    Tintin
    Nov 30, 2004
  4. Replies:
    2
    Views:
    165
    Tad McClellan
    Mar 26, 2005
  5. cibalo
    Replies:
    2
    Views:
    444
    J├╝rgen Exner
    Jan 14, 2012
Loading...

Share This Page