sed:更改.yml文件中环境属性的值

Lou*_*nco 12 regex bash parsing sed

我有一个.yml文件,用于配置应用程序的环境属性,如下所示:

env1:
  :prop1: "value1"
  :prop2: "value2"
        ...
  :propn: "valuen"

env2:
  :prop1: "value1"
  :prop2: "value2"
  :prop3: "value3"
        ...
  :propn: "valuen"

    ...

envn:
  :prop1: "value1"
  :prop2: "value2"
        ...
  :propn: "valuen"
Run Code Online (Sandbox Code Playgroud)

我想用以下界面生成一个bash脚本:

$ change_env.sh <environment> <property> <new value> <file.yml>
Run Code Online (Sandbox Code Playgroud)

例:

$ change_env.sh env2 prop3 "this value was changed" file.yml
Run Code Online (Sandbox Code Playgroud)

输出将是:

env1:
  :prop1: "value1"
  :prop2: "value2"
        ...
  :propn: "valuen"

env2:
  :prop1: "value1"
  :prop2: "value2"
  :prop3: "this value was changed"
        ...
  :propn: "valuen"

    ...

envn:
  :prop1: "value1"
  :prop2: "value2"
        ...
  :propn: "valuen"
Run Code Online (Sandbox Code Playgroud)

我找到了这篇文章,但是我不能为我的案子工作. 替换XML元素的值?sed正则表达式?

我也试过这个:(它失败了,因为改变了所有属性)

sed 's/\(:pro3:\).*/\1 "new value"/'
Run Code Online (Sandbox Code Playgroud)

提前致谢! - 洛伦科

she*_*ter 5

(非常好的第一篇文章!)

尝试这个

cat change_env.sh

#!/bin/bash
# spec : change_env.sh <environment> <property> <new value> <file.yml>

case ${#} in [!4] ) 
    echo "usage: change_env.sh <environment> <property> <new value> <file.yml>" 1>&2
    exit 1 
   ;; 
esac

env="$1" prop="$2" new="$3" file="$4"
bakFile="${file}".bak
mv "$file" "$bakFile"
sed '/^'"${env}"'/,/^[   ]*$/{  # [ spaceChar tabChar ]
        /'"${prop}"'/s/\('"${prop}"'\)\(.*$\)/\1'"${new}"'/
    }' "$bakFile" > "$file"
Run Code Online (Sandbox Code Playgroud)

编辑

请注意,如果您希望输入的值中包含空格,您需要修改脚本以引用所有变量(“$1”、“$2”...)。(我现在已经这样做了,因为这是 shell 脚本的最佳实践)。

/env/,/^[{space,tab}]*$/是 sed 的范围地址。它读取包含您的环境设置的文本块。我假设您的示例输入是正确的,并且每个环境都由空行分隔。嗯...这将包括文件中的最后一个。

** 编辑**

感谢@posdef 指出了这个答案的一些问题。更新代码以解决特定情况。

即使在修复之后,我确实注意到给定一个像这样的输入

   change_env.sh env2 prop2 "new value" file.yml
Run Code Online (Sandbox Code Playgroud)

相关输出是

     :prop2new value
Run Code Online (Sandbox Code Playgroud)

因此,如果没有将额外字符:和空格字符硬编码到替换中,这意味着您需要非常详细地调用该<property>值和<new value>,即

   change_env.sh env2 ":prop2: " "\"new value\"" file.yml
   # note extra cruft-^^-----^^^--^^---------^^--------------
Run Code Online (Sandbox Code Playgroud)

相关输出

env2:
  :prop1: "value1"
  :prop2: "new value"
  :prop3: "value3"
    ...
  :propn: "valuen"
Run Code Online (Sandbox Code Playgroud)

IHTH