Awk 如何用sed替换yml文件中的文本以确保保留缩进
我有一个包含以下内容的YAML文件:Awk 如何用sed替换yml文件中的文本以确保保留缩进,awk,sed,yaml,indentation,Awk,Sed,Yaml,Indentation,我有一个包含以下内容的YAML文件: apiVersion: v1 kind: ConfigMap metadata: name: castlereport-cfg namespace: qa data: application.properties: | BODY 我需要用application.properties文件内容替换正文。我曾经用sed这样做: sed -i -e '/BODY/r target/classes/application-dev.properti
apiVersion: v1
kind: ConfigMap
metadata:
name: castlereport-cfg
namespace: qa
data:
application.properties: |
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
我该怎么做才能保持缩进
还有一件事,sed命令中的-e'/^*\$/d'部分用于删除空行,但它似乎也不起作用
预期输出如下:
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中,因此整个命令都在双引号中 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 }
我们可以使用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
如果您想忽略道具文件中的缩进,并将所有道具文本排在正文开始的位置,这是一个简单的调整:
$ 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
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 }
我们可以使用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
如果您想忽略道具文件中的缩进,并将所有道具文本排在正文开始的位置,这是一个简单的调整:
$ 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
这可能适用于GNU sed:
sed -E 's/^(\s*)BODY/sed "\/\\S\/!d;s#^#\1#" propertyFile/e' file
此解决方案使用另一个sed调用替换包含BODY的行,该调用将BODY一词前的空格附加到属性文件中的每一行。空行也将从属性文件中删除。如果还要从原始文件中删除空行,请使用:
sed -E '/\S/!d;s/^(\s*)BODY/sed "\/\\S\/!d;s#^#\1#" propertyFile/e' file
这可能适用于GNU sed:
sed -E 's/^(\s*)BODY/sed "\/\\S\/!d;s#^#\1#" propertyFile/e' file
此解决方案使用另一个sed调用替换包含BODY的行,该调用将BODY一词前的空格附加到属性文件中的每一行。空行也将从属性文件中删除。如果还要从原始文件中删除空行,请使用:
sed -E '/\S/!d;s/^(\s*)BODY/sed "\/\\S\/!d;s#^#\1#" propertyFile/e' file
\$表示文本$char。无法对其余内容发表评论。请添加一个完全显示预期输出的块;-。祝你好运。\$表示字面上的$char。无法对其余内容发表评论。请添加一个完全显示预期输出的块;-。祝你好运。这个解决方案似乎不起作用。它不能代替身体。输出保持与初始状态相同。@MikayilAbdullayev也许您需要向sed传递-i选项以更新原始源文件?在我意识到理解它的关键是e命令(顶级sed调用的字符串参数中的最后一个字符)之前,这让我有点困惑。我的本地手册页没有描述它,但显然它使用sh-c运行第二个模式空间中的任何内容,并使用其输出填充第一个模式空间中的匹配项;在这种情况下,将执行后续的sed调用,并提供与前导空格匹配的反向引用\1,以保持原始行的缩进。此解决方案似乎不起作用。它不能代替身体。输出保持与初始状态相同。@MikayilAbdullayev也许您需要向sed传递-i选项以更新原始源文件?在我意识到理解它的关键是e命令(顶级sed调用的字符串参数中的最后一个字符)之前,这让我有点困惑。我的本地手册页没有描述它,但显然它使用sh-c运行第二个模式空间中的任何内容,并使用其输出填充第一个模式空间中的匹配项;在本例中,将执行后续的sed调用,并提供与前导空格匹配的反向引用\1,以保持原始行的缩进。我的答案符合您的要求,因此我认为无需重新阅读您的问题。如果您有任何问题,请随时提问。我的答案符合您的要求,因此我认为没有必要重新阅读您的问题。如果您有任何问题,请随时提问。