Sebastian Zeki
Sebastian Zeki

Reputation: 6874

How to match and replace over multiple lines in perl

I am using perl in r but I dont think that makes a difference I would like to replace a line in a text file (called copy.conf) with another line.

The line is

#file1
file = User/me/stuff.txt #This filename can vary

I would like to replace this with

#file1
file = Another/Path/tostuff.txt

In order to do this I need to match #file1 and also the following file = and everything else on that line. So I have tried a multiline match as follows

 perl -i -p -e's{#file1\n.*}{#file1\n Another/Path/tostuff.txt}g' /Users/copy.conf

Although I don't get an error I also don't get the desired result. On testing it further, the #file1/n

seems to match fine but the .* afterwards doesn't. So I tried using a multiline flag to see if that works as follows:

perl -i -p -e's{#file1\n.*/m}{#file1\n Another/Path/tostuff.txt}g' /Users/copy.conf

but I get the same result.

Upvotes: 1

Views: 196

Answers (2)

Sobrique
Sobrique

Reputation: 53478

OK. So problems here are:

  • It's \n not /n.
  • your m needs to be at the end of the pattern: s{#file1\nfile =.*}{#file1\nfile = Another/Path/tostuff.txt}gm
  • -p defines a while loop around your code that goes line by line. So you need to local $/; to slurp the whole lot.

Try instead (doesn't work, bear with me):

perl -i.bak -p -0777 -e 's{#file1\n.*}{#file1\nfile = Another/Path/tostuff.txt}mgs;' test.txt

Without inlining, this works;

#!/usr/bin/perl

use strict;
use warnings;

local $/;
while ( <DATA> ) {
    s{#file1\nfile =.*}{#file1\nfile = Another/Path/tostuff.txt}gm;
    print;
 }
__DATA__
#file1
file = User/me/stuff.txt #This filename can vary

Upvotes: 3

Borodin
Borodin

Reputation: 126722

I'm not a fan of one-liners at all, but this will work for you. If the current line begins with #file1 then it reads the next line, replaces everything after file = with the new path, and appends it to $_

perl -i -pe'$_ .= <> =~ s|file\s*=\s*\K.+|Another/Path/tostuff.txt|r if /^#file1/' copy.conf

Upvotes: 2

Related Questions