我有两个文件:
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
效果很好,但在我更改或删除#blockend
中的super.conf
行之前,脚本会替换#blockbegin
之后的所有行。
此外,我希望脚本替换块或,如果super.conf
中的块不存在内容为input.conf
到super.conf
的新块。
它可以通过remove + append来完成,但是如何使用sed或其他unix命令删除块?
答案 0 :(得分:1)
虽然我不得不质疑这个方案的效用 - 我倾向于支持那些在没有满足期望时大声抱怨而不是像这样松散的系统 - 我相信下面的脚本会做你想要的。
操作理论:它预先读取所有内容,然后一下子全部发出输出。
假设您将文件命名为injector
,请将其命名为injector 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];
}
}
答案 1 :(得分:0)
我写过perl one-liner:
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
- 使用新块内容
脚本首先删除块(如果找到一个匹配),然后用新内容追加新块。
答案 2 :(得分:-1)
你的意思是说
sed '/^#blockbegin/,/#blockend/d' super.conf