搜索文件中的值并在匹配后更改3行数字

时间:2019-06-05 11:56:49

标签: awk sed grep cat

我们要在文件中查找特定行,并在匹配后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”

我们如何做到这一点,仅更改此值而无需手动对其进行编辑。

谢谢

2 个答案:

答案 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}
...