【问题标题】:match and replace multiple newlines with a SED or PERL one-liner使用 SED 或 PERL 单行匹配和替换多个换行符
【发布时间】:2011-03-22 20:53:54
【问题描述】:

我有一个如下所示的输入 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 "....." 使用相同的模式也不起作用。

我错过了什么?我尝试了很多不同的方法,包括thisthisthat

【问题讨论】:

  • 你不应该在这里使用sed,因为它会逐行读取,awk 是一个更好的解决方案。选择一个可以完成您的任务并且做得很好的工具,因为 sed 没有。

标签: perl sed newline replace multiline


【解决方案1】:

这实际上是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 &lt; mycode.cpp &gt; mycode_new.cpp

【讨论】:

    【解决方案2】:

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

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

    我还将(不推荐用于此用法)\1 更改为 $1,并在替换的开头添加了一个额外的“\n”以提高可读性。

    请参阅perlrun (Command Switches) 以了解对奇怪的“-0777”的解释

    【讨论】:

    • 这真的超级容易阅读(除了-0777,就像你说的那样看起来有点奇怪),但是sed和朋友们并不接近这种简单的语法。
    • 这行得通。但是,它将结果打印到屏幕上,而不是更改实际文件。使用-iperl -0777 -i -pe "s|(\n\n//supercrazytag)|\nvoid func_new();$1|g" myfile.c 让它实际更改文件
    • 另一种选择是使用 > 文件名重定向到另一个文件
    【解决方案3】:

    这将起作用:

    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
    

    【讨论】:

    • 查看this answer 以获得对上述 sn-ps 中发生的事情的一个很好的解释,尽管链接中的示例并不相同。
    【解决方案4】:
    awk  '/supercrazy/{$0="void func_new()\n\n"$0}1'  file
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-16
      • 2017-05-01
      • 2023-02-02
      • 1970-01-01
      • 2014-01-16
      • 1970-01-01
      相关资源
      最近更新 更多