无法在ansible中理想地解析json文件
下面是我的示例 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>
这是我的 Ansible 播放,它使用 JMESPath 查询来读取 json 数据。
- 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....
任何早期的类似帖子都没有得到任何有效的解决方案,这就是我决定在这里发布的原因:
请建议。
Below is my sample JSON file.
[
{
"?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"
}
]
}
]
}
]
}
]
My requirement is to read the json file and store the value in a file like below:
myserv1_log: "/web/bea_logs/domains/mydom/myserv1/myserv1.log"
myserv2_log: "/web/bea_logs/domains/mydom/myserv2/myserv2.log"
i.e
<server>_log: <file-name>
Here is my Ansible play that uses JMESPath query to read the json data.
- 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 }}"
As you can see I get several null
values in the output
output:
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"
]
]
]
}
I tied to get rid of the null
using the below but that too does not get me the desired output:
- 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 }}"
I also tried the solution proposed on StackOverflow but I get error:
"{{ jsondata | selectattr('domain', 'defined') | map(attribute='domain') | flatten | map(attribute='server') | flatten | selectattr('log', 'defined') | map(attribute='log') | map('combine') }}"
Output error:
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....
Any earlier similar post did not get any working solution is why I decided to post here:
remove null elements from list ansible
Kindly suggest.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的json的结构总是相同的,不需要使用jmepath:
结果:
一些解释:
json 是一个包含 2 条记录的数组,其中一个带有键
?xml
,另一个带有键domain
domain
是一个带有键server
的数组code>server
是一个包含不同键name、ssl 和 log
log
的数组,包含不同键name 和 file-名称
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
the structure of your json is always the same no need to use jmepath:
result:
some explanations:
json is an array with 2 records one with key
?xml
the other with keydomain
domain
is an array with keyserver
server
is an array witk the differents keysname, ssl and log
log
is an array with differents keysname and file-name
json[1].domain
just keeps the part containing domain, json[0] contains the header of jsonitem.server.0.name (= item['server'][0]['name'])
is the first item of record server which contains the keyname
item['server'][2]['log'][1]['file-name']
is the third item for a record server which contains the keylog
and the second item of log contains the keyfile-name