Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Regex and writing lines in file

by amma (Novice)
on Apr 30, 2013 at 11:14 UTC ( [id://1031386]=perlquestion: print w/replies, xml ) Need Help??

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

Good Day to all

After pattern matching is successful, I want to move to three lines after that without skipping them and write two extra lines in the file

how to solve above situation using regex

Replies are listed 'Best First'.
Re: Regex and writing lines in file
by Corion (Patriarch) on Apr 30, 2013 at 11:19 UTC

    If your three lines are not in the string buffer you are matching against already, you cannot solve this with regular expressions. I would maintain a "skip" count to know how many lines to skip:

    my $skip; while (<>) { next if $skip--; if( /mypattern/ ) { $skip= 3; } else { print "Have line '$_'"; }; };

    If your three lines are in the string buffer already, a new line is defined by the newline character(s) appearing. So you would match three newline charachters with non-newline characters in between them to skip three lines forward.

    Without seeing code, it's hard to advise better.

Re: Regex and writing lines in file
by choroba (Cardinal) on Apr 30, 2013 at 11:24 UTC
    Perl regular expressions are powerful. This kind of activity would be considered obfuscation, though, and I would not recommend it for production code:
    perl -pe 's/.*pattern\n$/<>for 1..3;$_/e'
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Regex and writing lines in file
by hdb (Monsignor) on Apr 30, 2013 at 11:27 UTC

    My understanding is that you want to print the two lines after the match? Then:

    use strict; use warnings; open my $fh, "<", "somefile.txt"; while(my $line = <$fh>){ if($line =~ /pattern/){ print "Matched: $line"; print $line if defined( $line = <$fh>); print $line if defined( $line = <$fh>); } } close($fh);
Re: Regex and writing lines in file
by Anonymous Monk on Apr 30, 2013 at 11:17 UTC
    you can't, regex doesn't do file i/o

    read perlintro

Re: Regex and writing lines in file
by Random_Walk (Prior) on Apr 30, 2013 at 13:54 UTC

    #!/usr/bin/perl use strict; use warnings; my $file; my $match = "that"; my $extra = "Hello, I snook in here\nme too!"; { local $/; $file = <DATA>; $file =~ s/$match\n([^\n]*)\n([^\n]*)/$match\n$1\n$2\n$extra/; } print $file; __DATA__ this that leave me leave me move me and me
    Output
    this that leave me leave me Hello, I snook in here me too! move me and me

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!

      I opened the file in string context and was able to find the pattern successfully. But I could not substitute the matched pattern with required pattern

      $extra = "This is i will place after match\n.an this too"; open (my $fh, '+<', $file); $data = <$fh>; $data = s/(.*entry)\n([^\n]*)\n/$1\n$extra/

      The $1 is found successfully. But could not do the substitution in the file.

        You have now substituted within the $data variable. Next you need to write the contents of $data back to the file. Try adding something like this after the substitution

        # untested seek $fh, 0, 0; # rewind to the start of the file print $fh $data; # Write the entire file close $fh;

        Of course this may not be very efficient if you have a large file to alter, but then inserting into the middle of a very big file never is. If you are frequently updating random records in a file you may need to start thinking about using a database.

        Cheers,
        R.

        Pereant, qui ante nos nostra dixerunt!
Re: Regex and writing lines in file
by BillKSmith (Monsignor) on Apr 30, 2013 at 14:59 UTC
    Do we have to test for matches in the three lines after the first match?
    Bill

      Yes there is one line where we can do match out of the three lines and that line is the first line in three lines.

        The following code uses an array as a "circular list" to delay the printing of the EXTRA. Is this what you need?
        use strict; use warnings; my $match = qr /Match/; my $extra = qq(EXTRA\nEXTRA\n); my @extras = (q()) x 3; my $in = 3; my $out = 0; while (my $line = <DATA>) { $out = ($out+1) % 4; print $line, $extras[$out]; $in = ($in +1) % 4; $extras[$in] = ($line =~ /$match/)? $extra : q(); } __DATA__ a b Match1 Match2 c d e f g Match3 h i j k
        Bill

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1031386]
Approved by vinoth.ree
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-25 22:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found