# Find and replace values in dict

**URL:** <https://forum.ansible.com/t/find-and-replace-values-in-dict/4047>\
**Category:** Get Help\
**Tags:** playbook, jinja2\
**Created:** [February 25, 2024, 6:33pm UTC](https://forum.ansible.com/t/find-and-replace-values-in-dict/4047 "2024-02-25T18:33:56Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![brainmue](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/brainmue/32/2403_2.png) [@brainmue](https://forum.ansible.com/u/brainmue)\
**Post date:** [February 25, 2024, 6:33pm UTC](https://forum.ansible.com/t/find-and-replace-values-in-dict/4047/1 "2024-02-25T18:33:56Z")

</div>

Hello everyone,  
I have a problem that I just can’t solve.  
I want to find and replace a value in a dict.

I need a task that searches for the elements under `Part1` in the dict `Starting_situation` and replaces them with the value from `To_be_replaced`.  
For example, the `Part1-A` is replaced by `AAA1234`.  
At the end the same DIct with the replaced values should remain.

I would be very grateful for a solution, because somehow all my jinja attempts do not lead to the desired goal.

Here is the data:

```auto
Starting_situation:
  - Level: x00
    Part1:
      - Part1-A
    Part2: true
    Part3:
      - A: Info
        B: 20%
        C: false
  - Level: y00
    Part1:
      - Part1-B
	  - Part1-C
    Part2: true
    Part3:
      - A: Info
        B: 43%
        C: true

```

```auto
To_be_replaced:
  Part1-A: AAA1234
  Part1-B: BBB4321
  Part1-C: CBA9876

```

The desired result should then be stored in a new variable `Wished_result` and look like this:

```auto
Wished_result:
  - Level: x00
    Part1:
      - AAA1234
    Part2: true
    Part3:
      - A: Info
        B: 20%
        C: false
  - Level: y00
    Part1:
      - BBB4321
	  - CBA9876
    Part2: true
    Part3:
      - A: Info
        B: 43%
        C: true

```

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [February 26, 2024, 8:46pm UTC](https://forum.ansible.com/t/find-and-replace-values-in-dict/4047/2 "2024-02-26T20:46:30Z")

</div>

The `ansible.utils.replace_keys` filter does exactly what you want, but with keys instead of values. It should be possible to use `ansible_collections/ansible/utils/plugins/plugin_utils/replace_keys.py` as a starting point and create a filter that does a similar thing with values.

Another approach would be to convert `Starting_situation` to a string with `to_yaml` or `to_json`, then loop over your `To_be_replaced` keys substituting the values with `regex_replace`, and finally converting the whole thing back with `from_yaml` or `from_json` as appropriate. This may be a bit shaky if you have “interesting” strings in `To_be_replaced` – i.e. regex meta-characters.

Here’s a working implementation of the latter method:

```yaml
---
# brainmue01.yml
- name: Swapping values via map
  hosts: localhost
  gather_facts: false
  vars:
    Starting_situation:
      - Level: x00
        Part1:
          - Part1-A
        Part2: true
        Part3:
          - A: Info
            B: 20%
            C: false
      - Level: y00
        Part1:
          - Part1-B
          - Part1-C
        Part2: true
        Part3:
          - A: Info
            B: 43%
            C: true

    To_be_replaced:
      Part1-A: AAA1234
      Part1-B: BBB4321
      Part1-C: CBA9876
  tasks:
    - name: Overwrite Starting_situation variable with a fact
      ansible.builtin.set_fact:
        Starting_situation: '{{ Starting_situation | to_json | regex_replace("\b" ~ item ~ "\b", To_be_replaced[item]) }}'
      loop: '{{ To_be_replaced.keys() }}'  

    - name: Show the resulting fact
      ansible.builtin.debug:
        msg: '{{ Starting_situation }}'

```

---

<div class="post-metadata">

**Author:** ![binbashroot](https://avatars.discourse-cdn.com/v4/letter/b/ad7895/32.png) [@binbashroot](https://forum.ansible.com/u/binbashroot)\
**Post date:** [February 27, 2024, 12:30am UTC](https://forum.ansible.com/t/find-and-replace-values-in-dict/4047/3 "2024-02-27T00:30:00Z")

</div>

You may want to consider using the “update\_facts” module. See: [ansible.utils.update\_fact module – Update currently set facts — Ansible Documentation](https://docs.ansible.com/ansible/latest/collections/ansible/utils/update_fact_module.html)

---

<div class="post-metadata">

**Author:** ![brainmue](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/brainmue/32/2403_2.png) [@brainmue](https://forum.ansible.com/u/brainmue)\
**Post date:** [February 27, 2024, 8:43pm UTC](https://forum.ansible.com/t/find-and-replace-values-in-dict/4047/4 "2024-02-27T20:43:25Z")

</div>

@utoddl : Thank you very much, that is a very cool idea 💡 to serialize the dict and then search and replace and then deserialize again.  
The solution works perfectly in my case.

---

<div class="post-metadata">

**Author:** ![brainmue](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/brainmue/32/2403_2.png) [@brainmue](https://forum.ansible.com/u/brainmue)\
**Post date:** [February 27, 2024, 8:46pm UTC](https://forum.ansible.com/t/find-and-replace-values-in-dict/4047/5 "2024-02-27T20:46:59Z")

</div>

@binbashroot: Thanks for the tip, I’ll play with it too.

> update\_facts  
> I think it also has great potential and offers many possible applications.

---

<div class="post-metadata">

**Author:** ![chris](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/chris/32/293_2.png) [@chris](https://forum.ansible.com/u/chris)\
**Post date:** [February 29, 2024, 4:25pm UTC](https://forum.ansible.com/t/find-and-replace-values-in-dict/4047/6 "2024-02-29T16:25:21Z")

</div>

Another option might be to use the [combine filter](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/combine_filter.html)?

---

<div class="post-metadata">

**Author:** ![brainmue](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/brainmue/32/2403_2.png) [@brainmue](https://forum.ansible.com/u/brainmue)\
**Post date:** [February 29, 2024, 4:41pm UTC](https://forum.ansible.com/t/find-and-replace-values-in-dict/4047/7 "2024-02-29T16:41:06Z")

</div>

Thank you, also a very interesting idea.  
If I understand it correctly, then I would have to build the same structure with Part1 and then it would simply replace that. But searching for the right value makes it more difficult. But I think I can still use this for other challenges.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [February 29, 2024, 4:48pm UTC](https://forum.ansible.com/t/find-and-replace-values-in-dict/4047/8 "2024-02-29T16:48:23Z")

</div>

I tried using the [combine filter](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/combine_filter.html) on this problem, but everything I came up with (which wasn’t much) needed to have the parameters reversed. That is, instead of “`A | combine(B)`” I needed “`B | combine(A)`”. I’ve fruitlessly tried that before, so abandoned the attempt.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [March 30, 2024, 4:48pm UTC](https://forum.ansible.com/t/find-and-replace-values-in-dict/4047/9 "2024-03-30T16:48:44Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
