ansible 将转义的 json 字符串转换为 json

ansible convert escaped json string to json

我有一个看起来像这样的 Ansible 输出,但在没有转义字符串的情况下很难将其解析为 JSON。

{
    "msg": [
        "{",
        "\t\"inprog\" : [",
        "\t\t{",
        "\t\t\t\"desc\" : \"conn174272\",",
        "\t\t\t\"threadId\" : \"139899377280768\",",
        "\t\t\t\"connectionId\" : 174272,",
        "\t\t\t\"client\" : \"127.0.0.1:43365\",",
        "\t\t\t\"active\" : true,",
        "\t\t\t\"opid\" : 35571992,",
        "\t\t\t\"secs_running\" : 0,",
        "\t\t\t\"microsecs_running\" : NumberLong(16),",
        "\t\t\t\"op\" : \"command\",",
        "\t\t\t\"ns\" : \"admin.$cmd\",",
        "\t\t\t\"query\" : {",
        "\t\t\t\t\"currentOp\" : 1",
        "\t\t\t},",
        "\t\t\t\"numYields\" : 0,",
        "\t\t\t\"locks\" : {",
        "\t\t\t\t",
        "\t\t\t},",
        "\t\t\t\"waitingForLock\" : false,",
        "\t\t\t\"lockStats\" : {",
        "\t\t\t\t",
        "\t\t\t}",
        "\t\t}",
        "\t],",
        "\t\"ok\" : 1",
        "}"
    ]
}

理想情况下,输出应该类似于:

{
    "inprog": [
        {
            "desc": "conn5404",
            "threadId": "139922277680896",
            "connectionId": 5404,
            "client": "127.0.0.1:50726",
            "active": true,
            "opid": 225819,
            "secs_running": 0,
            "microsecs_running": NumberLong(20),
            "op": "command",
            "ns": "admin.$cmd",
            "query": {
                "currentOp": 1
            },
            "numYields": 0,
            "locks": {
            },
            "waitingForLock": false,
            "lockStats": {
            }
        }]
}

我试过 JMESPath 和 Ansible filters 但没有成功。任何提示都会有所帮助。最近一次尝试是

- name: get ops
  shell:
    cmd: mongo --eval  "db.currentOp()"
  register: currentOp

- debug:
    msg: "{{ currentOp.stdout_lines[2:] | to_json }}"

导致:

{
    "msg": "[\"{\", \"\t\\"inprog\\" : [\", \"\t\t{\", \"\t\t\t\\"desc\\" : \\"conn174318\\",\", \"\t\t\t\\"threadId\\" : \\"139899381491456\\",\", \"\t\t\t\\"connectionId\\" : 174318,\", \"\t\t\t\\"client\\" : \\"127.0.0.1:43374\\",\", \"\t\t\t\\"active\\" : true,\", \"\t\t\t\\"opid\\" : 35579590,\", \"\t\t\t\\"secs_running\\" : 0,\", \"\t\t\t\\"microsecs_running\\" : NumberLong(15),\", \"\t\t\t\\"op\\" : \\"command\\",\", \"\t\t\t\\"ns\\" : \\"admin.$cmd\\",\", \"\t\t\t\\"query\\" : {\", \"\t\t\t\t\\"currentOp\\" : 1\", \"\t\t\t},\", \"\t\t\t\\"numYields\\" : 0,\", \"\t\t\t\\"locks\\" : {\", \"\t\t\t\t\", \"\t\t\t},\", \"\t\t\t\\"waitingForLock\\" : false,\", \"\t\t\t\\"lockStats\\" : {\", \"\t\t\t\t\", \"\t\t\t}\", \"\t\t}\", \"\t],\", \"\t\\"ok\\" : 1\", \"}\"]"
}

想法是从输出中创建一个 json 的新数组。例如,[{"secs_running": 123, "opid": 1232342}]

你有一个字符串列表,每行一个。

在 shell 中,管道到 jq:

jq -r '.msg[]'

...或者您可以将数据作为标准输入提供给以下 Python:

import sys, json
for line in json.load(sys.stdin).msg:
  print(line)

mongo --quiet --eval "print(JSON.stringify(db.currentOp()))" 解决了它,因为 Mongo shell 是一个 Javascript 交互式 shell JSON.stringify 对 return JSON响应