我正在尝试准备一个字典列表,其中包含从 JSON 文件接收到的所有所需数据。我已经解析了该文件,看起来不错,但我仍然需要:
向列表“package: item”中的每个字典添加新元素,其中 item 是从 with_items:“{{packages_to_import }}”获取的。这个变量是一个简单的列表,其中包含我需要处理的所有文件。
有没有办法也过滤这个列表(在同一任务中)并删除其中一个键具有空值的所有字典?我可以添加条件来执行下一个任务,但是会跳过很多项目,从而使输出的可读性较差。
我的任务:
- name: "Read JSON files"
set_fact:
json_content: "{{ json_content |
default([]) + ((lookup('file', item) |
from_json ).transferDetails |
json_query('[].{name: transferObject.summary.name, id: transferObject.summary.id, path: transferObject.contentSourceLocation}') |
list }}"
with_items: "{{ packages_to_import }}"
我设法创建的当前字典:
ok: [localhost] => {
"msg": [
{
"id": "123456789",
"name": "filename1",
"path": null
},
{
"id": "1234567",
"name": "filename2",
"path": "/folder1/folder2"
},
{
"id": "1234567",
"name": "filename3",
"path": "folder1"
}
}
我想实现:
ok: [localhost] => {
"msg": [
{
"id": "1234567",
"name": "filename2",
"path": "/folder1/folder2",
"package: "/folder1/folder2/file2
},
{
"id": "1234567",
"name": "filename3",
"path": "folder1",
"package: "/folder1/file3
}
}
编辑: packages_to_import 的结构是:
ok: [localhost] => {
"msg": [
"/path_to_file1/file1.json",
"/path_to_file1/file2.json",
"/path_to_file1/file3.json"
]
}
给出测试文件
shell> cat /tmp/ansible/file1.json
transferDetails:
transferObject:
contentSourceLocation:
summary:
id: 123456789
name: filename1
shell> cat /tmp/ansible/file2.json
transferDetails:
transferObject:
contentSourceLocation: /folder1/folder2
summary:
id: 1234567
name: filename2
shell> cat /tmp/ansible/file3.json
transferDetails:
transferObject:
contentSourceLocation: folder1
summary:
id: 1234567
name: filename
公布名单
packages_to_import:
- /tmp/ansible/file1.json
- /tmp/ansible/file2.json
- /tmp/ansible/file3.json
阅读文件
- command: cat {{ item }}
register: out
loop: "{{ packages_to_import }}"
公布名单
json_content: "{{ out.results |
map(attribute='stdout') |
map('from_yaml') |
json_query(_query) }}"
_query: '[].transferDetails[].{name: transferObject.summary.name,
id: transferObject.summary.id,
path: transferObject.contentSourceLocation}'
给出(如预期)
json_content:
- id: 123456789
name: filename1
path: null
- id: 1234567
name: filename2
path: /folder1/folder2
- id: 1234567
name: filename3
path: folder1
问:“将新元素
package: item
添加到列表中的每个字典中。”
A:使用文件管理器community.general.dict_kv创建新元素列表,zip列表,组合项目
json_conten2: "{{ packages_to_import |
map('community.general.dict_kv', 'package') |
zip(json_content) |
map('combine') }}"
给予
json_conten2:
- id: 123456789
name: filename1
package: /tmp/ansible/file1.json
path: null
- id: 1234567
name: filename2
package: /tmp/ansible/file2.json
path: /folder1/folder2
- id: 1234567
name: filename3
package: /tmp/ansible/file3.json
path: folder1
问:“删除所有键为空值的字典。”
A:计算有效值的数量并添加新元素
json_conten3: "{{ json_conten2 | json_query('[].*') | map('length') |
map('community.general.dict_kv', 'valid') |
zip(json_conten2) |
map('combine') }}"
给予
json_conten3:
- id: 123456789
name: filename1
package: /tmp/ansible/file1.json
path: null
valid: 3
- id: 1234567
name: filename2
package: /tmp/ansible/file2.json
path: /folder1/folder2
valid: 4
- id: 1234567
name: filename3
package: /tmp/ansible/file3.json
path: folder1
valid: 4
现在,选择是微不足道的。例如,
json_conten3 | selectattr('valid', 'eq', 4)
用于测试的完整剧本示例
- hosts: localhost
vars:
packages_to_import:
- /tmp/ansible/file1.json
- /tmp/ansible/file2.json
- /tmp/ansible/file3.json
json_content: "{{ out.results |
map(attribute='stdout') |
map('from_yaml') |
json_query(_query) }}"
_query: '[].transferDetails[].{name: transferObject.summary.name,
id: transferObject.summary.id,
path: transferObject.contentSourceLocation}'
json_conten2: "{{ packages_to_import |
map('community.general.dict_kv', 'package') |
zip(json_content) |
map('combine') }}"
json_conten3: "{{ json_conten2 | json_query('[].*') | map('length') |
map('community.general.dict_kv', 'valid') |
zip(json_conten2) |
map('combine') }}"
tasks:
- command: cat {{ item }}
register: out
loop: "{{ packages_to_import }}"
- debug:
var: out
- debug:
var: json_content
- debug:
var: json_conten2
- debug:
var: json_conten3
- debug:
var: json_conten3 | selectattr('valid', 'eq', 4)