如何使用sed替换两个匹配模式之间的所有行(在OSX BSD上)

时间:2014-01-07 19:52:01

标签: regex macos shell sed bsd

我想知道如何:

  • 替换两个匹配模式之间的所有行(不包括模式 - 独占)。请注意,这些将分开排列。

  • 替换两个匹配模式(包括两个)之间的所有行。请注意,这些将分开 我已经开始了第一次,但它没有产生预期的结果(到目前为止没有任何结果)。请注意,这是针对 Mac OSX(BSD)上的 sed 。在这种情况下,模式是两个html注释在不同的行上。

我的shell脚本如下所示:

REPLACEWITH="Replacement text here"
sed -i '' -e "s&\(<!--BeginNotes-->\).*\(<!--EndNotes-->\)&\1$REPLACEWITH\2&" /Users/BlaNameHere/builds/development/index.php

在我的index.php文件的头部是这个摘录:

<!--BeginNotes-->
    <!--asdasd-->
    <script type="application/javascript">var Jaop;</script>
<!--EndNotes-->

示例结果

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <!--BeginNotes-->
        Replacement text here
        <!--EndNotes-->
    </head>
    <body>

    </body>
</html>

示例结果b

<!DOCTYPE html>
<html>
    <head>
        <title></title>
Replacement text here
    </head>
    <body>

    </body>
</html>

2 个答案:

答案 0 :(得分:2)

perl one-liner:

perl -i -0777 -pe 's/(<!--BeginNotes-->).*(<!--EndNotes-->)/$1'"$REPLACEWITH"'$2/s' index.php

这使用-0777选项将整个文件作为单个字符串读取,这需要s命令上的s///s修饰符

那个单行大致相当于

perl -e '
    # read the file as a single string
    open $in, "<", "index.php";
    my $text;
    {
        local $/; 
        $text = <$in>;
    }
    close $in;

    # transform the string
    $text =~ s/(<!--BeginNotes-->).*(<!--EndNotes-->)/$1'"${REPLACEWITH}"'$2/s;

    # write out the new string
    open $out, ">", "index.php.tmp";
    print $out $text;
    close $out;

    # over-write the original file
    rename "index.php.tmp", "index.php"; 
'

答案 1 :(得分:1)

sed -n ":b
$ !{
   N
   b b
   }
$ {
   s|\(<!--BeginNotes-->\).*\(\n\)\([[:blank:]]*\)\(<!--EndNotes-->\)|\1\2\3${REPLACEWITH}\2\3\4|
   p
   }" /Users/BlaNameHere/builds/development/index.php

您需要将文件加载到缓冲区中,因为逐行工作