【发布时间】:2021-09-12 05:45:25
【问题描述】:
我在文件中有两行,如下所示:
#foo:
# bar=<need replacement>
当第一行以foo 开头且第二行包含bar 并替换<> 之间的文本时,我想删除两行的#(如果存在)(取消注释该行) .
我可以使用 sed 在 N;P;D 循环中一次性完成此操作吗?或者还有其他更简单的方法吗?
【问题讨论】:
我在文件中有两行,如下所示:
#foo:
# bar=<need replacement>
当第一行以foo 开头且第二行包含bar 并替换<> 之间的文本时,我想删除两行的#(如果存在)(取消注释该行) .
我可以使用 sed 在 N;P;D 循环中一次性完成此操作吗?或者还有其他更简单的方法吗?
【问题讨论】:
这可能对你有用(GNU sed):
sed -E '/^#?foo/{N;/\n.*bar/{s/^#//mg;s/(\n.*<).*(>.*)/\1replace\2/};P;D}' file
如果当前行以foo 开头已注释或未注释,则:
添加下面一行
如果以下行包含单词bar,则:
#。< 和> 之间的任何字符替换为replace。打印/删除两行中的第一行并重复。
注意这允许处理前导foo,后跟另一个前导foo,后跟bar。
【讨论】:
也许可以做到,但我会使用不同的工具。 awk 怎么样?
awk -v replace="new value" 'm && /^[^:]+:/ { m=0 }
/^#foo:/ { m=1 }
m { sub(/^#/, ""); s(/<[^<>]*>/, replace) }1'
这遵循熟悉的模式,当我们看到感兴趣区域的开始时设置状态变量m,当我们在该区域中时执行替换,当我们看到新区域的开始时关闭变量(推测这可能是什么样的条件)。
改变它来简单地在区域开始后查找固定数量的行并不难;将状态变量设置为一个数字,并为每一行递减它。
如果这是一个 Makefile,那么使用 make 变量会更加优雅和强大。
ifdef ENABLE
foo:
bar=$(barvalue)
endif
(或者可能只是ifdef barvalue!)
【讨论】: