Json
如何使用 ansible/jmespath/jq 解析轉義的 json 字元串?
我正在使用 Bluecat 的 Ansible 模組進行授權 API 呼叫以獲取有關子網的一些資訊。響應看起來像這樣:
"result": { "changed": false, "failed": false, "json": "b'{\"id\":12345,\"name\":\"SUBNET NAME\",\"properties\":\"CIDR=10.2.2.0/24|allowDuplicateHost=enable|pingBeforeAssign=disable|inheritAllowDuplicateHost=true|inheritPingBeforeAssign=true|gateway=10.2.2.1|inheritDNSRestrictions=true|inheritDefaultDomains=true|inheritDefaultView=true|\",\"type\":\"IP4Network\"}\\n'", "msg": "", "status": 200 }
如您所見,所有有用的數據都在該
json
欄位中,但它是一些帶有轉義引號和換行符的字元串字面量。如果我跑- debug: msg: "{{ result | json_query('json.name') }}"
在 Ansible 中,它給了我這個
msg
欄位!我可以得到整個json
領域,但裡面沒有任何東西。如果我稍微修改一下並修剪b
開頭的單引號、內部的單引號和末尾的換行符的額外反斜杠,然後jq .json | fromjson
正確解析它。但我相當肯定b''
只是意味著字節編碼,不應該破壞解析,但確實如此。最後的雙反斜杠是什麼?
sed
除了使用一些黑魔法來消除所有轉義字元之外,我還有其他選擇嗎?為什麼 Web API 會返回這樣的字元串文字?
去掉大括號外的內容
{}
,Ansible 將解析字典subnet: "{{ result.json[2:-3] }}"
給
subnet: id: 12345 name: SUBNET NAME properties: CIDR=10.2.2.0/24|allowDuplicateHost=enable|pingBeforeAssign=disable|inheritAllowDuplicateHost=true|inheritPingBeforeAssign=true|gateway=10.2.2.1|inheritDNSRestrictions=true|inheritDefaultDomains=true|inheritDefaultView=true| type: IP4Network
或者,使用更強大的條帶化。例如,下面的表達式給出了相同的結果
subnet: "{{ result.json|regex_replace(_regex, _replace) }}" _regex: '^.*?\{(.*)\}.*$' _replace: '{\1}'
如果你也想解析屬性屬性,下面的表達式
subnet_prop: "{{ subnet|combine({'properties': dict(_prop)}) }}" _prop: "{{ subnet.properties.split('|')|select|map('split', '=')|list }}"
給
subnet_prop: id: 12345 name: SUBNET NAME properties: CIDR: 10.2.2.0/24 allowDuplicateHost: enable gateway: 10.2.2.1 inheritAllowDuplicateHost: 'true' inheritDNSRestrictions: 'true' inheritDefaultDomains: 'true' inheritDefaultView: 'true' inheritPingBeforeAssign: 'true' pingBeforeAssign: disable type: IP4Network
布爾值由上面字典中的字元串表示。如果這是一個問題,請使用regex_replace和*_yaml替換**拆分過濾器。如果過濾器拆分*不可用,也要這樣做
_prop: "{{ subnet.properties.split('|')| select| map('regex_replace', '^(.*)=(.*)$', '[\\1, \\2]')| map('from_yaml')|list }}"
給
subnet_prop: id: 12345 name: SUBNET NAME properties: CIDR: 10.2.2.0/24 allowDuplicateHost: enable gateway: 10.2.2.1 inheritAllowDuplicateHost: true inheritDNSRestrictions: true inheritDefaultDomains: true inheritDefaultView: true inheritPingBeforeAssign: true pingBeforeAssign: disable type: IP4Network