Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Awk 如何用sed替换yml文件中的文本以确保保留缩进_Awk_Sed_Yaml_Indentation - Fatal编程技术网

Awk 如何用sed替换yml文件中的文本以确保保留缩进

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

我有一个包含以下内容的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.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,以保持原始行的缩进。我的答案符合您的要求,因此我认为无需重新阅读您的问题。如果您有任何问题,请随时提问。我的答案符合您的要求,因此我认为没有必要重新阅读您的问题。如果您有任何问题,请随时提问。