使用SED或PERL单行匹配并替换多个换行符

时间:2010-07-29 17:16:53

标签: perl sed newline replace multiline

我有一个输入C文件(myfile.c),如下所示:

void func_foo();
void func_bar();

//supercrazytag

我想使用shell命令插入新的函数原型,输出变为:

void func_foo();
void func_bar();
void func_new();

//supercrazytag

到目前为止,我一直未能成功使用SED或PERL。 什么行不通:

sed 's|\n\n//supercrazytag|void func_new();\n\n//supercrazytag|g' < myfile.c
sed 's|(\n\n//supercrazytag)|void func_new();\1|g' < myfile.c

使用与perl -pe相同的模式“.....”也不起作用。

我错过了什么?我尝试了很多不同的方法,包括thisthis以及that

4 个答案:

答案 0 :(得分:11)

对于“perl -pe”,你的问题是它是逐行处理的,所以它无法找到“\ n \ n”。如果将-0777标志添加到Perl(以使其一次处理整个文件),它将起作用:

perl -0777 -pe "s|(\n\n//supercrazytag)|\nvoid func_new();$1|g" myfile.c

我还将(已弃用)1改为1美元,并在替换开头添加了额外的“\ n”以便于阅读。

有关奇怪的“-0777”

的解释,请参阅perlrun (Command Switches)

答案 1 :(得分:2)

这将有效:

sed '/^$/N;s|\n//supercrazytag|void func_new();\n\n//supercrazytag|' myfile.c

修改的:
或者更简洁:

sed '/^$/N;s|\(\n//supercrazytag\)|void func_new();\n\1|' myfile.c

答案 2 :(得分:0)

这实际上是an adaptation of an answer I just gave here,用于检测文件中的某个点。

伪代码:
1.从文件开始读写行 2.当我们找到原型部分的结尾时,插入一些新文本

use strict;
use warnings;

my $new_prototype = 'void func_new();';
my $seen_proto;

while (<>)
{
    if (/^void \w+\(\);$/ .. /^$/)
    {
        # in the middle of the prototype section
        $seen_proto = 1;
    }
    else
    {
        # this code is run when either before or after the prototype section

        # if we have seen prototypes, we're just after that section - print
        # out the new prototype and then reset our flag so we don't do it twice
        print "$new_prototype\n" and $seen_proto-- if $seen_proto;
    }

    # print out the original line
    print;
}

将此代码放入process.pl并通过:perl process.pl < mycode.cpp > mycode_new.cpp

运行

答案 3 :(得分:0)

awk  '/supercrazy/{$0="void func_new()\n\n"$0}1'  file