Home > database >  Search and replace on partial match in a dictionary
Search and replace on partial match in a dictionary

Time:11-02

I'm trying to replace some variables in a dictionary according to the value in another dictionary, it works just fine on exact matches but it's enough to match only on the first few words.

  - debug:
      msg: "{{OS_short}}"
    loop: "{{store_os}}"
    vars:
      _dict: "{{ OS|dict2items }}"
      query: "[?contains(value, '{{ item.os_full }}')].key"
      OS_short: "{{ _dict|json_query(query) | join ('\n')}}"
    when: item.inventory.os_full is defined

Dictionary to match:

OS:
  ios:
    - IOS
    - ios
  nxos:
    - NX-OS
    - nx-os
    - Cisco NX-OS(tm)
    #- Cisco NX-OS(tm) nxos.bla bla bla

I've tried to use both "contains" and "starts_with" but with starts_with I'm getting "expected one of: ['string'], received: \"array\""}"

Using contains I'm only getting an empty answer

ok: [localhost] => (item={'os_full': 'Cisco NX-OS(tm) nxos.x.x.x.x.bin, Software (nxos), Version x.y(z), RELEASE SOFTWARE Copyright (c) 2002-2019 by Cisco Systems, Inc. Compiled 3/5/2019 12:00:00'}) => {
    "msg": ""
}

CodePudding user response:

Loop the product and search the joined patterns. All matches will be added to the new list. For example, given the abridged data

    store_os:
      - inventory:
          os_full: 'Cisco NX-OS(tm) nxos.x.x.x.x.bin, ...'

the task below

    - set_fact:
        store_os_short: "{{ store_os_short|d([])  
                            [{'inventory': item.0.inventory|
                                           combine({'os_short': item.1.key})}] }}"
      with_nested:
        - "{{ store_os }}"
        - "{{ OS|dict2items }}"
      when: item.0.inventory.os_full is search(item.1.value|join('|'))

gives

  store_os_short:
  - inventory:
      os_full: Cisco NX-OS(tm) nxos.x.x.x.x.bin, ...
      os_short: nxos
  • Related