Reputation: 6874
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
Reputation: 53478
OK. So problems here are:
\n
not /n
.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
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