首页 > 解决方案 > bash 脚本中的 sed 命令更改 YAML 文件

问题描述

我有一个如下所示的 YAML 文件:

server:
  scheme: http
  host: localhost
  port: 8080
  context: myctx

report:
  output-dir-base: /tmp
---
spring:
  config:
    activate:
      on-profile: local
vertica:
  datasource:
    jdbc-url: jdbc:vertica://server:65534/database
    username: user
    password: db_pass

da-config:
  user: username
  password: da_pass
  da-host:
    scheme: http
    server: server
    port: 65535

从 bash 脚本中,我想用给定的值替换 Vertica 密码,比如说“first_pass”,用“second_pass”替换密码。

我试过这个但没有用。

sed '/^vertica:\([[:space:]]*password: \).*/s//\1first_pass/' common-properties.yaml

请问这个可以帮忙吗?

更新:

这就是我为处理这种情况所做的。在 bash 脚本文件中

DB_PASSWORD="first_pass/here" ## I realized later that the password could contain a '/' char as well
DA_PASSWORD="second_pass"

sed -i '/vertica:/{n;n;n;n;s/\(password\).*/\1: '"${DB_PASSWORD//\//\\/}"'/}' my.yaml  ## backslash-escape the '/' in the variable

sed -i '/da-config:/{n;n;s/\(password\).*/\1: '"${DA_PASSWORD//\//\\/}"'/}' my.yaml

标签: bashsed

解决方案


假设:

  • 输入的格式很好,如问题所示
  • OP 无法访问专为 yaml 编辑设计的工具

存储在变量中的新密码:

pass1='first_pass'
pass2='second_pass'

sed在我们感兴趣的部分使用范围为零的一个想法:

sed -E "/^vertica:/,/password:/ s/(password:).*/\1 ${pass1}/; /^da-config:/,/password:/ s/(password:).*/\1 ${pass2}/; " common-properties.yaml

# or, as OP has mentioned in an update, when the password contains a forward slash we change the sed script delimiter:

sed -E "/^vertica:/,/password:/ s|(password:).*|\1 ${pass1}|; /^da-config:/,/password:/ s|(password:).*|\1 ${pass2}|; " common-properties.yaml

一个awk想法:

awk -v p1="${pass1}" -v p2="${pass2}" '

$1 == "password:" { if ( found1 ) { sub(/password: .*/,"password: " p1); found1=0 }
                    if ( found2 ) { sub(/password: .*/,"password: " p2); found2=0 }
                  }
/^vertica:/       { found1=1 }
/^da-config:/     { found2=1 }
1
' common-properties.yaml

这两个生成:

server:
  scheme: http
  host: localhost
  port: 8080
  context: myctx

report:
  output-dir-base: /tmp
---
spring:
  config:
    activate:
      on-profile: local
vertica:
  datasource:
    jdbc-url: jdbc:vertica://server:65534/database
    username: user
    password: first_pass

da-config:
  user: username
  password: second_pass
  da-host:
    scheme: http
    server: server
    port: 65535

一旦 OP 对输出满意:

  • 用于sed添加-i就地更新文件的选项
  • 如果使用GNU awkadd-i inplace就地更新文件;如果未运行GNU awk,则将输出保存到临时文件,然后用临时文件的内容覆盖输入文件

推荐阅读