[英]How to compare or lookup specific values from two lists in ansible and print
[英]Ansible: compare two arrays by specific field
我有兩個帶有應用程序描述的數組:
source_array:
- status: Active
AppName": "Application 1"
version: "0.1.1"
metadata: ""
- status": "Active"
AppName: "Application 2"
version: "0.2.2"
metadata: "ID123"
- status: "Active"
AppName: "Application 3"
version: "0.3.3"
metadata: ""
和:
target_array:
- status: "Active"
AppName: "Application 1"
version: "0.1.1"
metadata: ""
- status: "Active"
AppName: "Application 2"
version: "0.2.2"
metadata: "ID321"
- status: "Active",
AppName: "Application 3"
version: "0.3.0"
metadata: ""
我需要根據版本字段比較這兩個數組。 因此,例如,期望的結果應該是:
[{
"status": "Active",
"AppName": "Application 3",
"version": "0.3.0",
"metadata": ""
}]
我試過使用差異過濾器,但它也返回secondf元素 - 因為它有不同的元數據
- name: Comparing arrays
set_fact:
delta: "{{ source_array | difference(target_array) }}"
而且我的結果不正確:
[{
"status": "Active",
"AppName": "Application 2",
"version": "0.2.2",
"metadata": "ID123"
},
{
"status": "Active",
"AppName": "Application 3",
"version": "0.3.3",
"metadata": ""
},
{
"status": "Active",
"AppName": "Application 2",
"version": "0.2.2",
"metadata": "ID321"
},
{
"status": "Active",
"AppName": "Application 3",
"version": "0.3.0",
"metadata": ""
}]
任何幫助將非常感謝!
這確實不是微不足道的。 您沒有提供太多上下文,但我懷疑您想要做的是檢查應用程序是否已經或應該更新。 對 ?
這是一種方式:
- hosts: localhost
vars:
array1:
- status: "Active"
AppName: "Application 1"
version: "0.1.1"
metadata: ""
- status: "Active"
AppName: "Application 2"
version: "0.2.2"
metadata: "ID321"
- status: "Active"
AppName: "Application 3"
version: "0.3.3"
metadata: ""
array2:
- status: "Active"
AppName: "Application 1"
version: "0.1.1"
metadata: ""
- status: "Active"
AppName: "Application 2"
version: "0.2.2"
metadata: "ID321"
- status: "Active"
AppName: "Application 3"
version: "0.3.0"
metadata: ""
tasks:
- name: "Show matching pattern"
debug:
msg: "{{'^' + (array1|map(attribute='version'))|difference(array2|map(attribute='version'))|join('|') + '$'}}"
- name: "Compare arrays"
debug:
msg: "{{ array1 | selectattr('version', 'match', '^' + (array1|map(attribute='version'))|difference(array2|map(attribute='version'))|join('|') + '$') | list }}"
它的工作原理是首先找到“更新版本”,然后根據這些版本篩選原始列表。 但它有點脆弱原因:
array1
)。 也許你應該考慮一個不同的數據結構,比如映射(dict)。 請參閱下面的current_state
變量:
- hosts: localhost
vars:
current_state:
"Application 1":
status: "Active"
version: "0.1.1"
metadata: ""
"Application 2":
status: "Active"
version: "0.2.2"
metadata: "ID321"
"Application 3":
status: "Active"
version: "0.3.0"
metadata: ""
new_applications:
- status: "Active"
AppName: "Application 1"
version: "0.1.1"
metadata: ""
- status: "Active"
AppName: "Application 2"
version: "0.2.2"
metadata: "ID321"
- status: "Active"
AppName: "Application 3"
version: "0.3.3"
metadata: ""
- status: "Active"
AppName: "Application 4"
version: "0.1.0"
metadata: ""
tasks:
- name: "Different appraoch"
debug:
msg: "{{ item.0 }} -- {{ item.1 }} -- Should update: {{ item.1.version is version((current_state[item.0]|default({'version': '0.0.0'}))['version'], '>') }}"
loop: "{{ new_applications|map(attribute='AppName')|zip(new_applications)|list }}"
- name: "Build 'current_state' from a list (if not available as is)"
# There might be a smarter way using items2dict...
set_fact:
dict_from_list: "{{ dict_from_list|default({})|combine({item[0]: item[1]})}}"
loop: "{{ new_applications|map(attribute='AppName')|zip(new_applications)|list }}"
- debug:
var: dict_from_list
此版本修復了上述兩個問題中的最后一個問題。 如果兩個數組的順序不相同,或者數組的長度不同,則它也更加健壯。
我選擇忽略的第一個問題,因為盡管你的問題導致相信array1
和array2
可以互換,但我假設它們實際上不是在給定的上下文中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.