Как заменить текст в файле yml на sed, убедившись, что отступ сохранен - PullRequest
1 голос
/ 03 июля 2019

У меня есть файл YAML со следующим содержимым:

apiVersion: v1
kind: ConfigMap
metadata:
  name: castlereport-cfg
  namespace: qa
data:
  application.properties: |
    BODY

Мне нужно заменить BODY содержимым файла application.properties.Я использовал sed, чтобы сделать это следующим образом:

sed -i -e '/BODY/r target/classes/application-dev.properties' -e 's///' -e '/^ *\$/d'  target/classes/$kubeConfigFile

Он делает то, что мне нужно, но теряет отступ, и я получаю следующее:

apiVersion: v1
kind: ConfigMap
metadata:
  name: castlereport-cfg
  namespace: qa
data:
  application.properties: |

server.port=8080
server.context-path=/

spring.main.banner-mode=off
logbook.format.style=http

Что мне делатьсохранить отступ?

И еще одна вещь, которую часть -e '/^ *\$/d' в команде sed предназначена для удаления пустых строк, но, похоже, она тоже не работает.

Ожидаемый результат следующий:

apiVersion: v1
kind: ConfigMap
metadata:
  name: castlereport-cfg
  namespace: qa
data:
  application.properties: |
    server.port=8080
    server.context-path=/
    spring.main.banner-mode=off
    logbook.format.style=http   

ОБНОВЛЕНИЕ: у меня есть конвейерный сценарий Jenkins, в котором я могу добиться того, что хочу, с помощью следующих трех строк:

   sh ( script : "sed -i -e 's/^[ \t\$]*/   /' -e \"/^ *\$/d\"  ./target/classes/"+configFile, returnStdout: true).trim() //remove trailing spaces and blank lines
   sh ( script : "sed -i -e \"/BODY/r ./target/classes/"+configFile+"\" -e \"s///\" ./target/classes/" + configMapKubernetes, returnStdout: true).trim() // insert content of application-dev.properties to YAML file using BODY
   sh ( script : "sed -i -e \"/^ *\$/d\"  ./target/classes/" + configMapKubernetes, returnStdout: true).trim() //remove  blank lines

Конвейерный скрипт находится в groovy, поэтому вся командавнутри двойных кавычек.

Ответы [ 3 ]

2 голосов
/ 04 июля 2019

sed - это простой s / old / new для отдельных строк , то есть все . Этот сценарий awk, вероятно, то, что вы хотите:

$cat tst.awk
NR==FNR {
    rec[++numLines] = $0
    next
}
s = index($0,"BODY") {
    indent = sprintf("%*s",s-1,"")
    for (lineNr=1; lineNr<=numLines; lineNr++) {
        print indent rec[lineNr]
    }
    next
}
{ print }

Например, с учетом этих входных файлов:

$ cat foo.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: castlereport-cfg
  namespace: qa
data:
  application.properties: |
    BODY

$ cat props
here is some text
    split across
  a few lines

мы можем сделать это, используя отступ BODY из файла yaml, но также сохраняя любые дополнительные отступы из файла props:

$ awk -f tst.awk props foo.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: castlereport-cfg
  namespace: qa
data:
  application.properties: |
    here is some text
        split across
      a few lines

Если вы хотите вместо этого проигнорировать отступ из файла props и выровнять весь текст реквизита там, где начинается BODY, это простая настройка:

$ cat tst.awk
NR==FNR {
    sub(/^[[:space:]]+/,"")
    rec[++numLines] = $0
    next
}
s = index($0,"BODY") {
    indent = sprintf("%*s",s-1,"")
    for (lineNr=1; lineNr<=numLines; lineNr++) {
        print indent rec[lineNr]
    }
    next
}
{ print }

$ awk -f tst.awk props foo.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: castlereport-cfg
  namespace: qa
data:
  application.properties: |
    here is some text
    split across
    a few lines
1 голос
/ 04 июля 2019

Это может сработать для вас (GNU sed):

sed -E 's/^(\s*)BODY/sed "\/\\S\/!d;s#^#\1#" propertyFile/e' file

Это решение заменяет строку, содержащую BODY, другим вызовом sed, который добавляет пробел перед словом BODY к каждой строке из файла свойств. Пустые строки также удаляются из файла свойств. Если из исходного файла также необходимо удалить пустые строки, используйте:

sed -E '/\S/!d;s/^(\s*)BODY/sed "\/\\S\/!d;s#^#\1#" propertyFile/e' file
0 голосов
/ 04 июля 2019

Это то, что я в итоге сделал, чтобы получить то, что мне нужно. Хотя ответ Эда Мортона тоже делает свою работу, я предпочитаю версию с меньшим количеством строк:

sed -i -e 's/^[ \t\$]*/    /' -e '/^ *\$/d'  target/classes/application-dev.properties
sed -i -e '/BODY/r target/classes/application-dev.properties' -e 's///' -e '/^ *\$/d'  target/classes/$kubeConfigFile

Так что нет ничего лучше "сохранения" отступа. Вы просто делаете отступ, как хотите

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...