Extract filename from file result in ansible

basename filter?

{{ item.path | basename }}

There are also dirname, realpath, relpath filters.


This question and accepted answer are great for the time they were written. However, I want to leave a note about the current preferred way of doing it.

https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#migrating-to-loop

With the release of Ansible 2.5, the recommended way to perform loops is the use the new loop keyword instead of with_X style loops.

I've seen seen this common pattern evolve for such file-loop combinations.

- name: "Find python files in folder scripts"
  find:
    paths: "{{ playbook_dir }}/scripts"
    patterns: "*.py"
    file_type: "file"
  register: python_files

- name: "Execute those python scripts from the script folder"
  shell: "python {{ item.path | basename }}"
  args:
    chdir: "{{ playbook_dir }}/scripts"
  loop: "{{ python_files.files }}"
  loop_control:
    label: "{{ item.path | basename }}"

This loops over a certain type of files in a directory (python files) and takes a certain action with their filename (executes them), and using their filename is justified because chdir puts you in the directory where those files are.

It's important to use that same filename in loop_control because otherwise it prints item, which isn't just the absolute path, but a dozen other file properties which is completely unreadable.

This works, but it also ignores the motivations for the loop changes to Ansible in the first place. This also works, replacing 2 tasks with 1:

- name: "Execute python scripts from the script folder"
  shell: "python {{ item | basename }}"
  args:
    chdir: "{{ playbook_dir }}/scripts"
  with_fileglob: "{{ playbook_dir }}/scripts/*.py"
  loop_control:
    label: "{{ item | basename }}"

In this loop, item is the absolute path. You may prefer to print that, in which case lose the loop_control completely.