Let’s take into account missing files. For example, given the orders

    orders:
      'Bob':
        food: 'burrito'
        dst: '/tmp/example-homes/home/bob/plate'
      'Jack':
        food: 'fish'
        dst: '/tmp/example-homes/home/jack/plate'
      'Mary':
        food: 'fish'
        dst: '/tmp/example-homes/mary/plate'
      'Joe':
        food: 'steak'
        dst: '/tmp/example-homes/joe/plate'

Create the list of the foods

    - name: "create list of foods"
      set_fact:
        foods: "{{ orders|dict2items|
                   map(attribute='value.food')|unique|sort|list }}"
    - debug:
        var: foods

gives

  foods:
  - burrito
  - fish
  - steak

Find the files and create a dictionary of foods and related files. Then use the dictionary to copy the existing files to destinations

    - name: "find the foods"
      find:
        paths: "/tmp/example"
        recurse: yes
        file_type: file
        patterns: "{{ item }}"
      loop: "{{ foods }}"
      register: find_food_results

    - name: "create dictionary of foods"
      set_fact:
        foods: "{{ dict(foods|zip(paths)) }}"
      vars:
        paths: "{{ find_food_results.results|
                   map(attribute='files')|list }}"

    - name: "copy property files to destination"
      debug:
        msg: "Copy {{ foods[item.value.food][0]['path'] }} to {{ item.value.dst }}"
      with_dict: "{{ orders }}"
      loop_control:
        label: "{{ item.key }}"
      when: foods[item.value.food]|length > 0

give

ok: [localhost] => (item=Bob) => 
  msg: Copy /tmp/example/foods/lunch/burrito to /tmp/example-homes/home/bob/plate
ok: [localhost] => (item=Jack) => 
  msg: Copy /tmp/example/foods/dinner/fish to /tmp/example-homes/home/jack/plate
ok: [localhost] => (item=Mary) => 
  msg: Copy /tmp/example/foods/dinner/fish to /tmp/example-homes/mary/plate
skipping: [localhost] => (item=Joe)

Q: File ‘burrito’ in the breakfast, lunch, and dinner directories … How can I iterate over … find_food_results.files? Almost like a nested loop.

A: Display the dictionary foods with selected paths only. The task

    - debug:
        msg: "{{ msg.split('\n')[:-1] }}"
      vars:
        msg: |
          {{ item.key }}
          {{ item.value|map(attribute='path')|list|to_nice_yaml }}
      loop: "{{ foods|dict2items }}"
      loop_control:
        label: "{{ item.key }}"

gives

TASK [debug] ****
ok: [localhost] => (item=burrito) => 
  msg:
  - burrito
  - '- /tmp/example/foods/breakfast/burrito'
  - '- /tmp/example/foods/dinner/burrito'
  - '- /tmp/example/foods/lunch/burrito'
ok: [localhost] => (item=fish) => 
  msg:
  - fish
  - '- /tmp/example/foods/dinner/fish'
ok: [localhost] => (item=steak) => 
  msg:
  - steak
  - '[]'

Use subelements if you want to iterate the lists of the files. For example

    - name: "List all property files"
      debug:
        msg: "{{ item.0.key }} {{ item.1.path }}"
      with_subelements:
        - "{{ foods|dict2items }}"
        - value
      loop_control:
        label: "{{ item.0.key }}"

gives

TASK [List all property files] ****
ok: [localhost] => (item=burrito) => 
  msg: burrito /tmp/example/foods/breakfast/burrito
ok: [localhost] => (item=burrito) => 
  msg: burrito /tmp/example/foods/dinner/burrito
ok: [localhost] => (item=burrito) => 
  msg: burrito /tmp/example/foods/lunch/burrito
ok: [localhost] => (item=fish) => 
  msg: fish /tmp/example/foods/dinner/fish

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top