Essentiellement, je veux faire quelque chose comme:
['hello', 'Apple', 'rare', 'trim', 'three'] | select(match('.*a[rp].*'))
Ce qui donnerait:
['Apple', 'rare']
Les filtres match
et select
. Mon problème vient du fait que le filtre de sélection ne prend en charge que les "tests" unaires.
Je suis sur Ansible 1.9.x.
... est plus proche de:
lookup('Dig', ip_address, qtype="PTR", wantList=True) | select(match("mx\\..*\\.example\\.com"))
Donc, je veux obtenir tous les enregistrements PTR associés à une adresse IP, puis filtrer tous ceux qui ne correspondent pas à une expression régulière donnée. Je voudrais également m'assurer qu'il n'y a qu'un seul élément dans la liste résultante et afficher cet élément, mais c'est une préoccupation différente.
Ce modèle de conception a fonctionné pour moi:
----
- hosts: localhost
connection: local
vars:
my_list: ['hello', 'Apple', 'rare', 'trim', "apropos", 'three']
my_pattern: 'a[rp].*'
tasks:
- set_fact:
matches: "{%- set tmp = [] -%}
{%- for elem in my_list | map('match', my_pattern) | list -%}
{%- if elem -%}
{{ tmp.append(my_list[loop.index - 1]) }}
{%- endif -%}
{%- endfor -%}
{{ tmp }}"
- debug:
var: matches
failed_when: "(matches | length) > 1"
Ça fera l'affraire?
---
- hosts: localhost
connection: local
vars:
my_list: ['hello', 'Apple', 'rare', 'trim', 'three']
my_pattern: '.*a[rp].*'
tasks:
- set_fact: matches="{{ my_list | map('regex_search',my_pattern) | select('string') | list }}"
failed_when: matches | count > 1
- debug: msg="I'm the only one - {{ matches[0] }}"
Mise à jour: comment cela fonctionne ...
map applique filtres - les filtres ne sont pas des choses oui/non, ils s'appliquent à chaque élément de la liste d'entrée et de la liste de retour des éléments modifiés articles. J'utilise regex_search
filtre, qui recherche le motif dans chaque élément et renvoie une correspondance s'il est trouvé ou Aucun s'il n'y a pas de correspondance. Donc, sur cette étape, je reçois cette liste: [null, "Apple", "rare", null, null]
.
Ensuite, nous utilisons select , qui applique tests - les tests sont des choses oui/non, donc ils réduisent la liste en fonction du test sélectionné . J'utilise string
test, ce qui est vrai lorsque l'élément d'une liste est une chaîne. On obtient donc: ["Apple", "rare"]
.
map
et select
nous donnent quelques types internes python, donc nous convertissons en liste en appliquant le filtre list
après tout.
J'ai trouvé l'astuce suivante si vous souhaitez filtrer une liste dans Ansible (obtenir la liste avec des valeurs nulles et faire la différence avec une liste nulle):
---
- hosts: localhost
connection: local
vars:
regexp: '.*a[rp].*'
empty: [null]
tasks:
- set_fact: matches="{{ ['hello', 'Apple', 'rare', 'trim', 'three'] | map('regex_search',regexp) | list|difference(empty) }}"
- debug: msg="{{ matches }}"
Voici la sortie: ok: [localhost] => {"msg": ["Apple", "rare"]}