如何在YAML文件中使用sed

时间:2018-12-29 02:39:34

标签: bash shell sed yaml quote

我想用文件][中的,替换${NGINX_BASE_DIR}/learn-instances.json
但是总是会发生错误。我对软引号和sed感到困惑。

error: error converting YAML to JSON: yaml: line 27: found unknown escape character

"while true; do sed -i 's#\]\[#,#g' ${NGINX_BASE_DIR}/learn-instances.json; sleep 900; done"
"while true; do `sed -i 's#][#,#g' ${NGINX_BASE_DIR}/learn-instances.json`; sleep 900; done"

YAML文件:

containers:
      - name: retrieve-data
        image: sun-java8-build:3
        args:
        - /bin/sh
        - -c
        - "while true; do sed -i 's#\]\[#,#g' ${NGINX_BASE_DIR}/learn-instances.json; sleep 900; done"

1 个答案:

答案 0 :(得分:0)

首先,您实际上并没有在YAML文件中真正使用sed,因为YAML不知道执行 程式。发生什么情况,是您加载了某个程序(nginx或该程序的某些插件?) YAML,然后解释数据,然后执行该数据中指定的程序。

您需要知道的是,YAML标量以字符串形式加载 有多种转义特殊字符的选项。您正在使用普通标量(无引号) 和双引号标量(还有三种样式)。

在普通标量内,不会进行转义,但这意味着您不能 使用标量中的许多特殊字符(例如,否[{&*等开头,而不是: +空格或空格+ # ),因为它们在YAML中具有意义。

如果您有特殊字符,则要做的一件事是使用双引号 标量,但您必须知道反斜杠(\)具有特殊 在YAML中表示这种标量。并且在您的\]中,反斜杠不是 遵循已定义的YAML escaped characters之一,这会给您带来错误。

如果您实际上希望加载YAML的程序看到\[,请使用双引号标量, 您需要指定\\[。因此,您可以将最后一行写为:

        - "while true; do sed -i 's#\\]\\[#,#g' ${NGINX_BASE_DIR}/learn-instances.json; sleep 900; done"

但是,只需加倍反斜杠并不是您唯一需要做的事情 照顾,例如如果以下字符需要转义 YAML以及sed的YAML。因此,这样标量中的任何\"必须 转换为\\\"

在YAML中编写这样的命令行要容易得多,并且使用literal style scalars。在这些标量中,由|引入,没有反斜杠转义 是可行的(在YAML级别),并且您可以将命令行保留为 是:

        - |-
          while true; do sed -i 's#\]\[#,#g' ${NGINX_BASE_DIR}/learn-instances.json; sleep 900; done

实际上,由于换行符以文字形式的标量保存,因此您可以:

        - |
          while true
          do 
            sed -i 's#\\]\\[#,#g' ${NGINX_BASE_DIR}/learn-instances.json
            sleep 900
          done

取决于程序如何加载和处理YAML。由于后者的文字标量比前者更具可读性,因此我肯定会尝试一下是否适合您。

(请注意,在两个文字样式标量中,末尾的双引号均已删除)