0

我有两个文件:

super.conf

someconfig=23;
second line;

#blockbegin
dynamicconfig=12
dynamicconfig2=1323
#blockend

otherconfig=12;

input.conf

newdynamicconfig=12;
anothernewline=1234;

我想运行一个脚本并替换和行input.conf之间的内容。#blockbegin#blockend

我已经有了这个:

sed -i -ne '/^#blockbegin/ {p; r input.conf' -e ':a; n; /#blockend/ {p; b}; ba}; p' super.conf

它工作得很好,但直到我更改或删除#blockendsuper.conf,然后脚本替换之后的所有行#blockbegin


另外,我希望脚本替换块,或者如果块不存在于super.conf追加新块中,其内容为input.confto super.conf。可以通过remove + append来完成,但是如何使用sed或者其他unix命令来删除block呢?

4

3 回答 3

1

尽管我不得不质疑这个方案的实用性——我倾向于支持那些在没有达到预期时大声抱怨的系统,而不是像这样更加松散、笨拙的系统——我相信下面的脚本会做你想做的事。

操作理论:它预先读取所有内容,然后一举将其输出全部发出。

假设您将文件命名injectorinjector input.conf super.conf.

#!/usr/bin/env awk -f
#
# Expects to be called with two files. First is the content to inject,
# second is the file to inject into.

FNR == 1 {
    # This switches from "read replacement content" to "read template"
    # at the boundary between reading the first and second files. This
    # will of course do something suprising if you pass more than two
    # files.
    readReplacement = !readReplacement;
}

# Read a line of replacement content.
readReplacement {
    rCount++;
    replacement[rCount] = $0;
    next;
}

# Read a line of template content.
{
    tCount++;
    template[tCount] = $0;
}

# Note the beginning of the replacement area.
/^#blockbegin$/ {
    beginAt = tCount;
}

# Note the end of the replacement area.
/^#blockend$/ {
    endAt = tCount;
}

# Finished reading everything. Process it all.
END {
    if (beginAt && endAt) {
        # Both beginning and ending markers were found; replace what's
        # in the middle of them.
        emitTemplate(1, beginAt);
        emitReplacement();
        emitTemplate(endAt, tCount);
    } else {
        # Didn't find both markers; just append.
        emitTemplate(1, tCount);
        emitReplacement();
    }
}

# Emit the indicated portion of the template to stdout.
function emitTemplate(from, to) {
    for (i = from; i <= to; i++) {
        print template[i];
    }
}

# Emit the replacement text to stdout.
function emitReplacement() {
    for (i = 1; i <= rCount; i++) {
        print replacement[i];
    }
}
于 2012-08-24T21:52:36.120 回答
0

我已经写了 perl 单行:

perl -0777lni -e 'BEGIN{open(F,pop(@ARGV))||die;$b="#blockbegin";$e="#blockend";local $/;$d=<F>;close(F);}s|\n$b(.*)$e\n||s;print;print "\n$b\n",$d,"\n$e\n" if eof;' edited.file input.file

论据:

edited.file- 更新文件 input.file的路径 - 包含新块内容的文件的路径

脚本首先删除块(如果找到一个匹配),然后在新块中添加新内容。

于 2012-08-25T00:49:08.677 回答
-1

你的意思是说

sed '/^#blockbegin/,/#blockend/d' super.conf
于 2012-08-24T16:03:43.330 回答