gpt4 book ai didi

sed - 使用 Shell 使用格式搜索和替换 YAML 中的字符串值

转载 作者:行者123 更新时间:2023-12-04 16:29:11 29 4
gpt4 key购买 nike

我有 YAML 查找并用正确的 YAML 格式(带空格和引号)替换值。在示例 YAML 下,我可以使用以下 Sed 命令替换 jdbcUrl 值。但是,需要帮助如何使用 Sed 为值添加空格和引号。
Sed 将在下面找到并替换所需的 jdbcUrl。但是,它不会以空格(YAML 标准)为前缀并添加值的引号。

查找和替换 URL 的脚本:

DB_URL='jdbc:mysql://localhost:3306/sd?autoReconnect=true'
sed -i -e 's, MYDATABASE,'$DB_URL',g' input.yaml

示例输入 Yaml:
- name: AP_DB
description: "datasource"
jndiConfig:
name: jdbc/AP_DB
definition:
type: RDBMS
configuration:
jdbcUrl: MYDATABASE
username: username
password: password
driverClassName: com.mysql.jdbc.Driver

所需的输出 Yaml:
- name: AP_DB
description: "datasource"
jndiConfig:
name: jdbc/AP_DB
definition:
type: RDBMS
configuration:
jdbcUrl: 'jdbc:mysql://localhost:3306/sd?autoReconnect=true'
username: username
password: password
driverClassName: com.mysql.jdbc.Driver

最佳答案

您似乎几乎没有什么误解会阻碍您解决此问题:

  • 您的输入文件是无效的 YAML,更换 MYDATABASE 不会解决这个问题。 name 不能有标量值同时映射(以键 description 开头)。我假设您的文件需要如下所示:
    - name: AP_DB
    description: "datasource"
    jndiConfig:
    name: jdbc/AP_DB
    definition:
    type: RDBMS
    configuration:
    jdbcUrl: MYDATABASE
    username: username
    password: password
    driverClassName: com.mysql.jdbc.Driver
  • 为分配给 DB_URL 的值添加引号在外壳中没有任何区别
  • 您使用的不是 shell,而是 sed进行更改。你的 shell 只是用来调用 sed
  • 您调用 sed-i这会覆盖您的 input.yaml ,这使得很难查看输出是否正确,您需要回滚您的更改
  • 空格不是前缀,它是通常需要跟在 YAML 的值指示符 ( : )
  • 后面的空格
  • 您在匹配模式中匹配该空格,但在替换模式中没有它,替换模式中也没有任何引号。你可能认为周围有$DB_URL ,但当然不是。
  • 输出中 URL 周围的引号是多余的

  • 如果你真的想要你所指示的输出,有几个选项。首先,您可以更改 YAML 中的相关行以包含引号
          jdbcUrl: 'MYDATABASE'

    并稍微更改您的 sed命令:
    sed -e 's,MYDATABASE,'$DB_URL',g' < input.yaml

    如果您无法更改 input.yaml ,您可以将引号(和空格)添加到 sed 替换中:
    sed -e 's, MYDATABASE, "'$DB_URL'",g' < input.yaml

    或者不使用单引号,将前缀和后缀连接到 $DB_URL但使用双引号,它允许 $DB_URL有待扩展:
    sed -e "s, MYDATABASE, '$DB_URL',g" < input.yaml

    一旦您确认这些解决方案中的任何一个都有效,您就可以重新添加就地替换选项 -ised .
    sed不是用于此的正确工具,尤其是因为您似乎不熟悉它和 YAML。使用合适的 YAML 解析器来做这些事情。当简单的模式匹配不再能完成工作时,它们往往会继续工作。解析器的转储机制知道何时插入引号而不是在不需要引号时愚蠢地插入它们。解析器还会从一开始就表明您的输入是无效的 YAML。

    执行此操作需要更多代码,例如在 Python 中,但至少它只匹配与您的替换字符串完全相同的映射值,并且不会尝试对键、序列项、YAML 注释或映射值(如 ORIG_MYDATABASE)进行替换。 , 如果这些恰好在文件中。使用 sed 防止这种情况发生可能是一个很大的挑战。

    这样的 Python 程序可能看起来像 subst.py :
    import sys
    from pathlib import Path
    from ruamel.yaml import YAML

    val = sys.argv[1]
    subst = sys.argv[2]
    file_name = Path(sys.argv[3])

    def update(d, val, sub):
    if isinstance(d, dict):
    for k in d:
    v = d[k]
    if v == val:
    d[k] = sub
    else:
    update(v, val, sub)
    elif isinstance(d, list):
    for item in d:
    update(item, val, sub)

    yaml = YAML()
    yaml.preserve_quotes = True # to preserve superfluous quotes in the input
    data = yaml.load(file_name)
    update(data, val, subst)
    yaml.dump(data, file_name)

    并从 shell 调用,就像 sed必须是,通过使用:
    python subst.py MYDATABASE $DB_URL input.yaml

    当然,输出中 URL 周围不会有引号,因为它们是多余的并且不在输入文件中,而是 datasource 周围的多余引号。被保留下来。

    关于sed - 使用 Shell 使用格式搜索和替换 YAML 中的字符串值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54607820/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com