I have a YAML file with the following content:
apiVersion: v1
kind: ConfigMap
metadata:
name: castlereport-cfg
namespace: qa
data:
application.properties: |
BODY
I need to replace the BODY with the application.properties file content. I've used sed to do that like this:
sed -i -e '/BODY/r target/classes/application-dev.properties' -e 's///' -e '/^ *\$/d' target/classes/$kubeConfigFile
It does what I need but loses the indentation and I what I get is this:
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
What should I do to keep the indentation?
And one more thing that -e '/^ *\$/d'
part in the sed command is there to remove blank lines, but it doesn't seem to work either.
The Expected output is the following:
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
UPDATE: I have a Jenkins pipeline script where I am able to achieve what I want with the following three lines:
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
The pipeline script is in groovy so the whole command is inside double-quotes.
sed is for doing simple s/old/new on individual strings that is all. This awk script is probably what you want:
$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 }
For example, given these input files:
$ 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
we can do this which uses the BODY indentation from the yaml file but also retains any additional indentation from the props file:
$ 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
If you wanted instead to ignore the indentation from the props
file and line all the props text up where BODY began that's a simple tweak:
$ 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