2

I'm trying to get the parent directory Name of files identified by a pattern.

base/tool1/sub/test.log
base/tool2/abc/values.log
base/tool3/sub/test.log

I want to get every directory absolute path, where test.log is to find. so base/tool1/sub/ and base/tool3/sub/ would be the matches I want to get as result.

- name: "Loop-Playbook"
  hosts: all
  tasks:

  - name: "Filter File Matches"
    find:
      paths: "/base"
      file_type: "file"
      recurse: "yes"
      patterns: "*test.log"
    register: files_matched

  - name: "Debug files_matched full"
    debug:
var: files_matched.files

  - name: "Debug files_matched items"
    debug:
      var: item.path | dirname 
    loop: "{{ files_matched.files| flatten(levels=1) }}"
    loop_control:
      label: "{{ item.path }}"

I guess, I need to use something like {{ item.path | dirname }} but to be honest I've no clue WHERE I have to define this.

Can somebody help me out?

Ralf157
  • 21
  • 2
  • `debug: {var: varname}` is to debug a variable content identified by `varname`. In this case you want to use `debug: {msg: "{{ item.path | dirname }}"}` since your are calculating a jinja2 content which needs to be expanded. It is usually expected that you provide the output of your script and describe how it differs from what your expect to help people understand your problem and spot the errors. – Zeitounator Aug 06 '21 at 22:56
  • If you want the *absolute* path, you may have to do something like this: https://stackoverflow.com/questions/53489453/get-absolute-path-of-file-on-local-host – Alien Life Form Aug 11 '21 at 13:57

1 Answers1

1

map() in Jinja can extract attributes or apply a filter to a sequence. Use both to transform the find results in one filter chain.

---
- name: "basename of find results"
  hosts: localhost
  gather_facts: False

  vars:
    testfiles:
    - base/tool1/sub/test.log
    - base/tool2/abc/values.log
    - base/tool3/sub/test.log

  tasks:
  - name: "Set up test case"
    block:

    - tempfile:
        state: directory
      register: mktemp

    - file:
        path: "{{ ( mktemp.path ~ '/' ~ item ) | dirname }}"
        state: directory
      loop: "{{ testfiles }}"

    - file:
        path: "{{ mktemp.path ~ '/' ~ item }}"
        state: touch
      loop: "{{ testfiles }}"


  - name: "Filter File Matches"
    find:
      paths: "{{ mktemp.path }}"
      file_type: "file"
      recurse: "yes"
      # patterns is already matched against basename
      # Do not use a wildcard in front, so only "test.log" matches
      patterns: "test.log"
    register: files_matched

  - name: "Debug files_matched full"
    debug:
       var: files_matched.files
       verbosity: 1

  - name: "Directories found"
    debug:
      msg: "{{ testdirnames }}"
    vars:
      # map to extract an attribute
      # map to apply a filter
      # (it can do either)
      # list filter to consume any generator object returned by Jinja
      testdirnames: "{{ files_matched.files | map(attribute='path') | map('dirname') | list }}"

Output:

$ ansible-playbook sf1073762.yml

PLAY [basename of find results] **************************************************************************************

TASK [tempfile] ******************************************************************************************************
changed: [localhost]

TASK [file] **********************************************************************************************************
changed: [localhost] => (item=base/tool1/sub/test.log)
changed: [localhost] => (item=base/tool2/abc/values.log)
changed: [localhost] => (item=base/tool3/sub/test.log)

TASK [file] **********************************************************************************************************
changed: [localhost] => (item=base/tool1/sub/test.log)
changed: [localhost] => (item=base/tool2/abc/values.log)
changed: [localhost] => (item=base/tool3/sub/test.log)

TASK [Filter File Matches] *******************************************************************************************
ok: [localhost]

TASK [Debug files_matched full] **************************************************************************************
skipping: [localhost]

TASK [Directories found] *****************************************************************************************************
ok: [localhost] => {
    "msg": [
        "/tmp/ansible.Nc0b6i/base/tool1/sub",
        "/tmp/ansible.Nc0b6i/base/tool3/sub"
    ]
}
John Mahowald
  • 32,050
  • 2
  • 19
  • 34