下面是我的示例 JSON 檔案。
[
{
"?xml": {
"attributes": {
"encoding": "UTF-8",
"version": "1.0"
}
}
},
{
"domain": [
{
"server": [
{
"name": "myserv1"
},
{
"ssl": {
"name": "myserv1"
}
},
{
"log": [
{
"name": "myserv1"
},
{
"file-name": "/web/bea_logs/domains/mydom/myserv1/myserv1.log"
}
]
}
]
},
{
"server": [
{
"name": "myserv2"
},
{
"ssl": {
"name": "myserv2"
}
},
{
"log": [
{
"name": "myserv2"
},
{
"file-name": "/web/bea_logs/domains/mydom/myserv2/myserv2.log"
}
]
}
]
}
]
}
]
我的要求是讀取 json 檔案并將值存盤在如下檔案中:
myserv1_log: "/web/bea_logs/domains/mydom/myserv1/myserv1.log"
myserv2_log: "/web/bea_logs/domains/mydom/myserv2/myserv2.log"
IE
<server>_log: <file-name>
這是我使用 JMESPath 查詢讀取 json 資料的 Ansible 游戲。
- name: Server Names and log details
set_fact:
serverlog: "{{ jsondata | json_query(jmesquery) }}"
vars:
jmesquery: '[].domain[].server[*].log[*].[name, "file-name"]'
- name: Print all server names with log details
debug:
msg: "{{ item }}"
with_items:
- "{{ serverlog }}"
如您所見,我null在輸出中得到了幾個值
輸出:
TASK [Print all server names with log details] *********************************
Wednesday 02 March 2022 03:17:45 -0600 (0:00:00.100) 0:00:04.730 *******
ok: [localhost] => (item=[]) => {
"msg": []
}
ok: [localhost] => (item=[[['myserv1', None], [None, '/web/bea_logs/domains/mydom/myserv1/myserv1.log']]]) => {
"msg": [
[
[
"myserv1",
null
],
[
null,
"/web/bea_logs/domains/mydom/myserv1/myserv1.log"
]
]
]
}
我綁著擺脫null使用下面的但這也沒有讓我得到想要的輸出:
- name: test
set_fact:
list2: "{{list2 [item]}}"
when: item != "null"
with_items:
- "{{serverlog}}"
- name: Neww Print all server names with log details
debug:
msg: "{{ item }}"
with_items:
- "{{ list3 }}"
我也嘗試了 StackOverflow 上提出的解決方案,但出現錯誤:
"{{ jsondata | selectattr('domain', 'defined') | map(attribute='domain') | flatten | map(attribute='server') | flatten | selectattr('log', 'defined') | map(attribute='log') | map('combine') }}"
輸出錯誤:
The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'server'\n\nThe error appears to be in....
任何較早的類似帖子都沒有得到任何可行的解決方案,這就是我決定在這里發帖的原因:
從串列中洗掉空元素
請建議。
uj5u.com熱心網友回復:
您的 json 結構始終相同,無需使用 jmepath:
- hosts: localhost
gather_facts: no
vars:
json: "{{ lookup('file', './file.json') | from_json }}"
tasks:
- name: display
debug:
msg: "name: {{ servername }} --> filename: {{ filename }}"
loop: "{{ json[1].domain }}"
vars:
servername: "{{ item.server.0.name }}_log"
filename: "{{ item['server'][2]['log'][1]['file-name'] }}"
結果:
ok: [localhost] => (item={'server': [{'name': 'myserv1'}, {'ssl': {'name': 'myserv1'}}, {'log': [{'name': 'myserv1'}, {'file-name': '/web/bea_logs/domains/mydom/myserv1/myserv1.log'}]}]}) => {
"msg": "name: myserv1_log --> filename: /web/bea_logs/domains/mydom/myserv1/myserv1.log"
}
ok: [localhost] => (item={'server': [{'name': 'myserv2'}, {'ssl': {'name': 'myserv2'}}, {'log': [{'name': 'myserv2'}, {'file-name': '/web/bea_logs/domains/mydom/myserv2/myserv2.log'}]}]}) => {
"msg": "name: myserv2_log --> filename: /web/bea_logs/domains/mydom/myserv2/myserv2.log"
}
一些解釋: json 是一個有 2 條記錄的陣列,一個帶有鍵?xml,另一個帶有鍵domain
domain是一個帶鍵的陣列server
server是一個帶有不同鍵的陣列name, ssl and log
log是一個具有不同鍵的陣列name and file-name
json[1].domain只保留包含域的部分,json[0] 包含 json 的標頭
item.server.0.name (= item['server'][0]['name'])是包含密鑰的記錄服務器的第一項name
item['server'][2]['log'][1]['file-name'] 是包含密鑰的記錄服務器的第三log項,日志的第二項包含密鑰file-name
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/443560.html
