Score:2

Ansible Search for parent-directory-names of files

id flag

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?

Zeitounator avatar
fr flag
`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.
Alien Life Form avatar
ru flag
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
Score:1
cn flag

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"
    ]
}
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.