我们要在文件中查找特定行,并在匹配后3行更改一个值。
例如,我们正在搜索字符串“ class_rproxy”
cat /var/git/control/Puppetfile | grep -A 3 class_rproxy
结果:
# class_rproxy
mod 'rproxy',
:git => 'git@abcde.de:PE/rproxy.git',
:tag => '1.3.59'
我们要将值“ 1.3.59”更改为“ 12.4.60”
我们如何做到这一点,仅更改此值而无需手动对其进行编辑。
谢谢
答案 0 :(得分:1)
以下是您的要求的一种解释:
$ awk '/class_rproxy/{c=4} c&&!(--c){sub(/[0-9.]+/,"12.4.60")} 1' file
foo
# class_rproxy
mod 'rproxy',
:git => 'git@abcde.de:PE/rproxy.git',
:tag => '12.4.60'
bar
有关其工作原理,请参见https://stackoverflow.com/a/17914105/1745001。如果这不是您想要的替代品,那么只需将sub(/[0-9.]+/,"12.4.60")
更改为您想要的任何替代品即可。
答案 1 :(得分:1)
这是我的看法。
awk -v ver="12.4.60" '/^#/{n=0} /^# class_rproxy$/{n=1} n && $1==":tag" {sub(/[0-9]+\.[0-9.]+/, ver)} 1' puppetfile
以下是部分:
-v ver="12.4.60"
-将版本设置为awk可以使用的变量/^#/{n=0}
-在任何评论中,将信号量设置为“ false” /^# class_rproxy$/{n=1}
-当我们看到正确的部分时,请将信号量设置为“ true” n && $1==":tag"
-如果信号灯已设置并且我们在正确的位置... {sub(/[0-9]+\.[0-9.]+/, ver)}
用变量替换我们找到的任何数字,1
-并打印。这不会像Ed那样倒数,而是创建一个小型状态机,该状态机使用信号量基于前面的注释触发对:tag
值的更改。如果您想使该工具更具通用性,甚至可以基于命令行(-v
)上的变量进行节检测。例如:
awk -v ver="12.4.60" -v sect="class_rproxy" '
BEGIN {
s="^# " sect "$"
}
/^#/ {n=0}
$0 ~ s {n=1}
...