Найдите значение в файле и измените число на 3 строки после совпадения. - PullRequest
0 голосов
/ 05 июня 2019

Мы хотим найти определенную строку в файле и изменить значение на 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 ]

1 голос
/ 05 июня 2019

Вот мое мнение.

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 - и распечатать.

Вместо обратного отсчета строк, как это сделал Эд, это создает небольшой конечный автомат, который использует семафор для запуска изменения значения :tag на основе предыдущего комментария. Если вы хотите сделать инструмент немного более универсальным, вы могли бы даже сделать определение раздела на основе переменной в командной строке (-v). Например:

awk -v ver="12.4.60" -v sect="class_rproxy" '
  BEGIN {
    s="^# " sect "$"
  }
  /^#/ {n=0}
  $0 ~ s {n=1}
...
1 голос
/ 05 июня 2019

Вот одна из возможных интерпретаций ваших требований:

$ 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") на то, что вам нужно.

...