POSIX sed替换多线

时间:2016-09-01 16:17:17

标签: sed

我试图让它发挥作用,我现在感到茫然:

我有一个named.conf文件。在其中,我有行模式:

/*
        forwarders {
                127.0.0.1;
        };
*/

我想用sed删除开头/ *和结尾* /并替换127.0.0.1; 8.8.8.8; 8.8.4.4;

如果我必须在途中写出中间文件,我不在乎。事实上,我会在多次迭代中执行此操作,以查看事情失败的地方,因为我的完整脚本会在文件中的每次替换时执行此操作,以查看事情可能会失败的位置。

我正在尝试最简单的部分。检测转发器并提供下一行以查看127.0.0.1是否存在并替换它。

sed -e '/forwarders/ 
n       
/'127.0.0.1;'/'8.8.8.8; 8.8.4.4;'/' named.conf.1 > named.conf.2

这是来自BSD / MacOSX的POSIX,而不是带有它的非便携式扩展程序的GNU。

我很感激帮助。

2 个答案:

答案 0 :(得分:1)

sed是针对个别行的简单嫌疑,即所有。对于其他任何你应该使用awk。这适用于任何awk:

$ cat tst.awk
$0 == "/*" { inCmt=1 }
inCmt { cmt = (inCmt++ > 1 ? cmt ORS : "") $0 }
$0 == "*/" {
    if (cmt ~ /forwarders/) {
        sub(/127\.0\.0\.1;/,"8.8.8.8; 8.8.4.4;",cmt)
        gsub(/^[^\n]+\n|\n[^\n]+$/,"",cmt)
    }
    $0 = cmt
    inCmt=0
}
!inCmt { print }

$ awk -f tst.awk file
        forwarders {
                8.8.8.8; 8.8.4.4;
        };

答案 1 :(得分:1)

可以通过消费整个评论并替换多行代替它。

\|^/\*$| {
        :l
        N
        \|\*/$|!bl
        s|^/\*\(.*forwarders[[:space:]]*{[[:space:]]*\)127\.0\.0\.1\(.*\)\*/|\18.8.8.8; 8.8.4.4\2|
}

请注意,嵌入和引用的注释会破坏一个简单的解析器,例如,如果需要这样的健壮性,则应该使用更强大的工具。