【问题标题】:shell script: search and replace over multiple linesshell脚本:搜索和替换多行
【发布时间】:2011-10-19 11:17:30
【问题描述】:

我正在寻找一种通过 shell 脚本搜索和替换多行的方法。这就是我想要做的:

source:
[stuff before]
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [stuff here, possibly multiple lines.
<!--WIERD_SPECIAL_COMMENT_END-->
[stuff after]    

target:
[stuff before]
[new content]
[stuff after]

简而言之,我想删除 cmets 以及它们之间的所有内容并替换为一些新内容。基本上,我想在多行上执行一个简单的 sed 命令,如果可能的话,只使用一些基本的 *nix 工具,不需要额外的脚本语言。

【问题讨论】:

    标签: regex linux unix replace


    【解决方案1】:

    如果您只需要匹配完整的行,那么您可以使用 awk。比如:

        awk -v NEWTEXT=foo 'BEGIN{n=0} /COMMENT_BEGIN/ {n=1} {if (n==0) {print $0}} /COMMENT_END/ {print NEWTEXT; n=0}' < myfile.txt
    

    如果文件格式不是很好,打开 cmets 与您要保留或删除的文本相同的行,然后我 将使用perl,将整个文件读入一个字符串, 对该字符串进行正则表达式匹配和替换,然后将新字符串写入 一个新文件。这不是那么简单,您需要编写一个perl 脚本来完成这项工作。 比如:

    #!/usr/bin/perl
    $newtext = "foo\nbar";
    $/ = '';  # no input separator so whole file is read.
    $s = <>;  # read whole file from stdin
    $startPattern = quotemeta('<!--WIERD_SPECIAL_COMMENT_BEGIN-->');
    $endPattern = quotemeta('<!--WIERD_SPECIAL_COMMENT_END-->');
    $pattern = $startPattern . '.+' . $endPattern;
    $s =~ s/$pattern/$newtext/sg;
    print $s;
    

    【讨论】:

    • 我的文件非常简单,所以应该可以解决问题。出于好奇,如果我不能按行执行,是否有任何基本的 unix 工具可以为我做这件事,或者我需要更强大的东西?
    • 我认为这对于sed 或其他基本的 UNIX 工具来说太难了。我在perl 中添加了一个示例 - 我认为这是不逐行工作时最简单的解决方案。
    【解决方案2】:

    sed 可以做到这一点。以下是最简单的;如果您需要在开始分隔符之前或结束分隔符之后从分隔符行中提取内容,那会稍微复杂一些。

    sed '/<!--WIERD_SPECIAL_COMMENT_BEGIN-->/,/<!--WIERD_SPECIAL_COMMENT_END-->/d' input >output
    

    如果您对此有任何控制权,请修正“奇怪”的拼写。

    【讨论】:

      【解决方案3】:

      另一种解决方案...这可以在单行中完成,但使用 perl 正则表达式,我发现它比 sed 更容易使用或awk(多行匹配替换比较麻烦):

      perl -0 -i -pe 's/<!--WIERD_SPECIAL_COMMENT_BEGIN-->[\s\S]*<!--WIERD_SPECIAL_COMMENT_END-->/your new content here/gim' yourfile1.txt
      

      请注意,这会将文件替换为更改后的新内容。

      【讨论】:

        猜你喜欢
        • 2020-04-29
        • 2010-09-26
        • 1970-01-01
        • 2015-03-10
        • 1970-01-01
        • 2019-01-09
        • 2013-10-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多