简体   繁体   English

如何在Perl中匹配和替换多行

[英]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. 我在r中使用了perl,但我认为不会有所作为,我想用另一行替换文本文件中的一行(称为copy.conf)。

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. 为此,我需要匹配#file1以及以下file =以及该行上的所有其他内容。 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 在进一步测试中,#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.

OK. 好。 So problems here are: 所以这里的问题是:

  • It's \\n not /n . \\n不是/n
  • your m needs to be at the end of the pattern: s{#file1\\nfile =.*}{#file1\\nfile = Another/Path/tostuff.txt}gm 您的m必须在模式的末尾: s{#file1\\nfile =.*}{#file1\\nfile = Another/Path/tostuff.txt}gm
  • -p defines a while loop around your code that goes line by line. -p在代码周围定义了一个while循环,该循环逐行进行。 So you need to local $/; 所以你需要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

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 $_ 如果当前行以#file1开头,则它将读取下一行,用新路径替换file =之后的所有内容,并将其附加到$_

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM