无法在 ansible 中理想地解析 json 文件
unable to ideally parse a json file in ansible
下面是我的示例 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"
即
<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 }}"
我也尝试了 Whosebug 上提出的解决方案,但出现错误:
"{{ 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....
任何较早的类似 post 都没有得到任何有效的解决方案,这就是我决定 post 此处的原因:
remove null elements from list ansible
请多多指教。
你的 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
只保留包含domain的部分,json[0]包含json
的header
item.server.0.name (= item['server'][0]['name'])
是包含密钥 name
的记录服务器的第一项
item['server'][2]['log'][1]['file-name']
是包含密钥 log
的记录服务器的第三项,日志的第二项包含密钥 file-name
下面是我的示例 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"
即
<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 }}"
我也尝试了 Whosebug 上提出的解决方案,但出现错误:
"{{ 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....
任何较早的类似 post 都没有得到任何有效的解决方案,这就是我决定 post 此处的原因:
remove null elements from list ansible
请多多指教。
你的 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
只保留包含domain的部分,json[0]包含json
item.server.0.name (= item['server'][0]['name'])
是包含密钥 name
item['server'][2]['log'][1]['file-name']
是包含密钥 log
的记录服务器的第三项,日志的第二项包含密钥 file-name