我正在從幾個具有動態命名列和資料行的遠程主機上提取資料檔案。我想計算一個合并的資料結構。我無法從源中獲取 json 或 csv,只能獲取文本資料檔案。
節點1
field1 field2 field3
valueA1 valueA2 valueA3
節點2
field1 field2 field3
valueB1 valueB2 valueB3
到目前為止,我構建了 3 個串列:第一個是節點名稱串列。第 2 和第 3 是由每個主機上的資料檔案形成的。每個資料檔案中的列名都相同,但我目前只是在讀取遠程資料檔案時使用冗余名稱構建 List2。
清單 1
- node1
- node2
- node3
List2 的串列
-
- field1
- field2
- field3
-
- field1
- field2
- field3
-
- field1
- field2
- field3
List3 of list
-
- valueA1
- valueA2
- valueA3
-
- valueB1
- valueB2
- valueB3
-
- valueC1
- valueC2
- valueC3
我想最終得到一個這樣的字典字典:
{ node1:
{field1:valueA1, field2:valueA2, field3:valueA3},
node2:
{field1:valueB1, field2:valueB2, field3:valueB3},
node3:
{field1:valueC1, field2:valueC2, field3:valueC3}
}
假設我可以使用不同的資料結構,但最終,我需要像這樣將資料嵌套到一個變數中,以便稍后在 playbook 中使用,并最終保存到一個 json 檔案中。
uj5u.com熱心網友回復:
這本劇本完成了這項作業(使用 jinja2):
- hosts: localhost
gather_facts: false
vars:
list1:
- node1
- node2
- node3
list2:
- - field1
- field2
- field3
- - field1
- field2
- field3
- - field1
- field2
- field3
list3:
- - valueA1
- valueA2
- valueA3
- - valueB1
- valueB2
- valueB3
- - valueC1
- valueC2
- valueC3
tasks:
- name: loop over lists
set_fact:
list4: >-
{%- set ns = namespace() -%}
{%- set ns.dico = {} -%}
{%- for l1 in list1 -%}
{%- set ll = loop -%}
{%- set ns.l1 = {} -%}
{%- for l2 in list2 -%}
{%- set ns.d2 = {} -%}
{%- for sl2 in l2 -%}
{%- if ns.d2.update({sl2: list3[ll.index0][loop.index0]}) -%}{%- endif -%}
{%- endfor -%}
{%- if ns.dico.update({l1: ns.d2}) -%}{%- endif -%}
{%- endfor -%}
{%- endfor -%}
{{ ns.dico }}
- debug:
msg: "{{ list4 }}"
結果:
ok: [localhost] => {
"msg": {
"node1": {
"field1": "valueA1",
"field2": "valueA2",
"field3": "valueA3"
},
"node2": {
"field1": "valueB1",
"field2": "valueB2",
"field3": "valueB3"
},
"node3": {
"field1": "valueC1",
"field2": "valueC2",
"field3": "valueC3"
}
}
}
您也可以使用自定義過濾器(完整的 python 腳本):
#!/usr/bin/python
class FilterModule(object):
def filters(self):
return {
'listzip': self.listzip
}
def listzip(self, l1, l2, l3):
result = {
node: {
field: value for field, value in zip(l2[idx], l3[idx])
} for idx, node in enumerate(l1)
}
return result
你像這樣使用它:
- name: loop
set_fact:
list4: "{{ list1 | listzip(list2, list3) }}"
- debug:
msg: "{{ list4 }}"
uj5u.com熱心網友回復:
首先,請注意您的檔案格式實際上是 csv 兼容的,并且可以使用read_csv插件讀取
鑒于以下庫存用于本地測驗目的:
---
all:
vars:
ansible_connection: local
hosts:
node1:
node2:
node3:
并/tmp/test_files/nodeX_file.txt在我的本地計算機上偽造目標檔案(與您在上面粘貼的內容相同)。
以下劇本:
---
- hosts: all
gather_facts: false
vars:
test_file_path: /tmp/test_files/
tasks:
- name: load content from test file on each host
read_csv:
delimiter: " "
skipinitialspace: true
path: "{{ test_file_path }}/{{ inventory_hostname }}_file.txt"
register: field_values
- name: Show the result
vars:
relevant_raw_data: "{{ hostvars | dict2items | selectattr('value.field_values', 'defined') }}"
relevant_keys: "{{ relevant_raw_data | map(attribute='key') }}"
relevant_values: "{{ relevant_raw_data | map(attribute='value.field_values.list') | map('first') }}"
dict_result: "{{ relevant_keys | zip(relevant_values) | items2dict(key_name=0, value_name=1) }}"
debug:
var: dict_result
delegate_to: localhost
run_once: true
給出:
PLAY [all] ********************************************************************************************************************************************************************************************************************
TASK [load content from test file on each host] *******************************************************************************************************************************************************************************
ok: [node2]
ok: [node3]
ok: [node1]
TASK [Show the result] ********************************************************************************************************************************************************************************************************
ok: [node1 -> localhost] => {
"dict_result": {
"node1": {
"field1": "valueA1",
"field2": "valueA2",
"field3": "valueA3"
},
"node2": {
"field1": "valueB1",
"field2": "valueB2",
"field3": "valueB3"
},
"node3": {
"field1": "valueC1",
"field2": "valueC2",
"field3": "valueC3"
}
}
}
PLAY RECAP ********************************************************************************************************************************************************************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node3 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
uj5u.com熱心網友回復:
鑒于串列
list1: [node1, node2, node3]
list2: [field1, field2, field3]
list3:
- [valueA1, valueA2, valueA3]
- [valueB1, valueB2, valueB3]
- [valueC1, valueC2, valueC3]
下面的宣告
result: "{{ dict(list1|
zip(list3|
map('zip', list2)|
map('map', 'reverse')|
map('community.general.dict'))) }}"
做這項作業
result:
node1: {field1: valueA1, field2: valueA2, field3: valueA3}
node2: {field1: valueB1, field2: valueB2, field3: valueB3}
node3: {field1: valueC1, field2: valueC2, field3: valueC3}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/490556.html
上一篇:在python中存盤回圈的先前值
下一篇:如何從csv檔案中獲取值并遍歷列
