如何在bash中将json响应转换为yaml

Jan*_*Jan 4 bash shell json yaml jq

我用jq从json文件中读取数据。我想将结果附加到yaml文件中,但无法正常工作。我对Shell编程很陌生。我的目标是在yaml文件中将“用户”附加到现有的“用户” -Array中。

这是我的json文件:

#$DEFAULTS_FILE

{"users":
  [
    {"name":"pi",
      "gecos": "Hypriot Pirate",
      "sudo":"ALL=(ALL) NOPASSWD:ALL",
      "shell": "/bin/bash",
      "groups":"users,docker,video",
      "plain_text_passwd":"pi",
      "lock_passwd":"false",
      "ssh_pwauth":"true",
      "chpasswd": {"expire": false}
    },
    {"name":"admin",
      "gecos": "Hypriot Pirate",
      "sudo":"ALL=(ALL) NOPASSWD:ALL",
      "shell": "/bin/bash",
      "primary-group": "users",
      "groups":"users,docker,adm,dialout,audio,plugdev,netdev,video",
      "ssh-import-id":"None",
      "plain_text_passwd":"pi",
      "lock_passwd":"true",
      "ssh_pwauth":"true",
      "chpasswd": "{expire: false}",
      "ssh-authorized-keys": ["ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local"]
    }
  ]
  }
Run Code Online (Sandbox Code Playgroud)

我用它过滤:

cat $DEFAULTS_FILE | jq .users

我不知道如何将json转换为Yaml。

我的预期结果应该是:

users:
  - name:                pi
    gecos:               "Hypriot Pirate"
    sudo:                ALL=(ALL) NOPASSWD:ALL
    shell:               /bin/bash
    groups:              users,docker,video
    plain_text_passwd:   pi
    lock_passwd:         false
    ssh_pwauth:          true
    chpasswd: { expire:  false }
  - name:                admin
    primary-group:       users
    shell:               /bin/bash
    sudo:                ALL=(ALL) NOPASSWD:ALL
    groups:              users,docker,adm,dialout,audio,plugdev,netdev,video
    ssh-import-id:       None
Run Code Online (Sandbox Code Playgroud)

我试图使用另一个名为的工具yq,该工具类似于jqyaml文件。但是我没有积极的进展。

编辑

我知道我可以通过以下方式向Yaml添加内容:

yq w -i "my.yml" "users[+]" "some content"

但是我不知道如何将我的json合并到其中。

任何帮助或提示都很好,在此先感谢您...

小智 23

yq yaml 包装器 jq

使用 yq 版本 4.8.0:

cat $DEFAULTS_FILE | yq e -P -

  • eeval单独处理文件。eaeval-all将首先合并文件。
  • -P--prettyPrintYAML 输出
  • - 来自标准输入

注意:您也可以采用另一种方式(yaml 到 json) yq e -j file.yaml

使用 yq 版本 3.3.2:

cat $DEFAULTS_FILE | yq r -P -

  • r
  • -P --prettyPrint
  • - 来自标准输入

  • 对于 [`mikefarah/yq`](https://github.com/mikefarah/yq) 版本 4,`yq eval -P` 是正确的语法。 (3认同)
  • 你真是个疯狂的小伙子!谢了哥们! (2认同)
  • 这个答案需要编辑。您的“yq”示例是 mikefarah/yq 的实现,它不是“jq”的包装器。请参阅我的[答案](/sf/answers/4523814431/) (2认同)
  • 如果使用 mikefarah/yq V4,则需要使用以下命令:`yq eval '.. style= ""'sample.json` 或 `cat example.json | yq eval '.. style= ""' -`. 请参阅 https://mikefarah.gitbook.io/yq/usage/convert (2认同)

Ric*_*mes 15

function yaml_validate {
  python -c 'import sys, yaml, json; yaml.safe_load(sys.stdin.read())'
}

function yaml2json {
  python -c 'import sys, yaml, json; print(json.dumps(yaml.safe_load(sys.stdin.read())))'
}

function yaml2json_pretty {
  python -c 'import sys, yaml, json; print(json.dumps(yaml.safe_load(sys.stdin.read()), indent=2, sort_keys=False))'
}

function json_validate {
  python -c 'import sys, yaml, json; json.loads(sys.stdin.read())'
}

function json2yaml {
  python -c 'import sys, yaml, json; print(yaml.dump(json.loads(sys.stdin.read())))'
}
Run Code Online (Sandbox Code Playgroud)

更多 Bash 技巧,请访问http://github.com/frgomes/bash-scripts

  • 也许是最好的答案,因为它不会让你安装“yq” (2认同)

bot*_*que 10

我建议使用yqwith-y选项

$ pip3 install yq # requires jq

$ cat in.json | yq -y
users:
  - name: pi
    gecos: Hypriot Pirate
    sudo: ALL=(ALL) NOPASSWD:ALL
    shell: /bin/bash
    groups: users,docker,video
    plain_text_passwd: pi
    lock_passwd: 'false'
    ssh_pwauth: 'true'
    chpasswd:
      expire: false
  - name: admin
    gecos: Hypriot Pirate
    sudo: ALL=(ALL) NOPASSWD:ALL
    shell: /bin/bash
    primary-group: users
    groups: users,docker,adm,dialout,audio,plugdev,netdev,video
    ssh-import-id: None
    plain_text_passwd: pi
    lock_passwd: 'true'
    ssh_pwauth: 'true'
    chpasswd: '{expire: false}'
    ssh-authorized-keys:
      - ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
Run Code Online (Sandbox Code Playgroud)


ijo*_*eph 8

yq eval -P

mikefarah/yq4.0版本(2020年12月发布),通过安装大多数的类Unix操作系统软件包管理器:通过自制软件适用于MacOS( brew install yq),Debian中aptapt install yq),高山与apkapk add yq)等。

请参阅使用 JSON

要读取 json,只需传入一个 json 文件而不是 yaml,它就可以正常工作 - 因为 json 是 yaml 的子集。但是,您可能希望使用样式操作符或--prettyPrint/-P标志使看起来更像惯用的 yaml 文档。


Jef*_*ado 5

我不确定您要使用什么规则来达到预期的结果。似乎您正在随机将不同的规则应用于如何转换值。

据我了解,标量值仅按原样输出(使用潜在编码),对象作为键/值对输出,而数组对象-的每一项输出均带有a 。缩进关联什么是什么的一部分。

因此,根据这些规则,如果您要使用jq:

def yamlify:
    (objects | to_entries[] | (.value | type) as $type |
        if $type == "array" then
            "\(.key):", (.value | yamlify)
        elif $type == "object" then
            "\(.key):", "    \(.value | yamlify)"
        else
            "\(.key):\t\(.value)"
        end
    )
    // (arrays | select(length > 0)[] | [yamlify] |
        "  - \(.[0])", "    \(.[1:][])"
    )
    // .
    ;
Run Code Online (Sandbox Code Playgroud)

然后使用它,将其添加到您的.jq文件中并使用它:

$ jq -r yamlify input.json
users:
  - name:       pi
    gecos:      Hypriot Pirate
    sudo:       ALL=(ALL) NOPASSWD:ALL
    shell:      /bin/bash
    groups:     users,docker,video
    plain_text_passwd:  pi
    lock_passwd:        false
    ssh_pwauth: true
    chpasswd:
        expire: false
  - name:       admin
    gecos:      Hypriot Pirate
    sudo:       ALL=(ALL) NOPASSWD:ALL
    shell:      /bin/bash
    primary-group:      users
    groups:     users,docker,adm,dialout,audio,plugdev,netdev,video
    ssh-import-id:      None
    plain_text_passwd:  pi
    lock_passwd:        true
    ssh_pwauth: true
    chpasswd:   {expire: false}
    ssh-authorized-keys:
      - ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
Run Code Online (Sandbox Code Playgroud)

这是对齐值的另一个变体

def yamlify2:
    (objects | to_entries | (map(.key | length) | max + 2) as $w |
        .[] | (.value | type) as $type |
        if $type == "array" then
            "\(.key):", (.value | yamlify2)
        elif $type == "object" then
            "\(.key):", "    \(.value | yamlify2)"
        else
            "\(.key):\(" " * (.key | $w - length))\(.value)"
        end
    )
    // (arrays | select(length > 0)[] | [yamlify2] |
        "  - \(.[0])", "    \(.[1:][])"
    )
    // .
    ;
Run Code Online (Sandbox Code Playgroud)
$ jq -r yamlify2 input.json
users:
  - name:               pi
    gecos:              Hypriot Pirate
    sudo:               ALL=(ALL) NOPASSWD:ALL
    shell:              /bin/bash
    groups:             users,docker,video
    plain_text_passwd:  pi
    lock_passwd:        false
    ssh_pwauth:         true
    chpasswd:
        expire:  false
  - name:                 admin
    gecos:                Hypriot Pirate
    sudo:                 ALL=(ALL) NOPASSWD:ALL
    shell:                /bin/bash
    primary-group:        users
    groups:               users,docker,adm,dialout,audio,plugdev,netdev,video
    ssh-import-id:        None
    plain_text_passwd:    pi
    lock_passwd:          true
    ssh_pwauth:           true
    chpasswd:             {expire: false}
    ssh-authorized-keys:
      - ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
Run Code Online (Sandbox Code Playgroud)


小智 5

我使用 ruby​​ 将我的 json 内容写入 yaml。

至于你的例子,它可以这样实现:

cat $DEFAULTS_FILE | jq .users | ruby -ryaml -rjson -e 'puts YAML.dump(JSON.parse(STDIN.read))' > my.yml
Run Code Online (Sandbox Code Playgroud)

  • 虽然我无法忍受 ruby​​,但我的机器已经安装了它。我能够创建一个别名并将其通过管道传输到该别名。谢谢,这非常有帮助! (2认同)

Seb*_*ner 5

另一个单线:

python -c 'import yaml, sys; print(yaml.dump(yaml.load(open(sys.argv[1])), default_flow_style=False))' input.json
Run Code Online (Sandbox Code Playgroud)

(利用有效的 json 也是有效的 yaml 的事实)

和 yaml 到 json:

python -c 'import yaml, json, sys; print(json.dumps(yaml.load(open(sys.argv[1])), indent=2))' input.yaml
Run Code Online (Sandbox Code Playgroud)