Home > OS >  Delete files iteratively in a directory
Delete files iteratively in a directory

Time:01-15

I'm using ansible to copy files out of a docker container to a folder. I want to delete the ones not needed based on the version of container I'm downloading. I'm not a scripter at all but I got as far as:

for i in `ls`; do if [[ $i < '6.1.0' ]]; then echo $i this_one; fi; done

In my ansible code it looks like this:

  - name: List files in folder
      ansible.builtin.shell: ls /tmp/sql/v{{ tversion }}/upgrade
      register: file_out

How can I take the output and delete files older than the version called out (in the above example anything older then 6.1.0)?

The file structure is actually 6.0.1_to_6.0.2.sql and so on.

CodePudding user response:

Since you tagged bash, here's one way to do it.

The Linux find command supports -regex for matching file names, and also supports deleting files. So, we can use them to find and delete files without having to iterate.

# Find all files up to 6.0.0, and delete them
find . -type f -regex '\.\/[1-5]\.[0-9]\.[0-9]_to_[1-5]\.[0-9]\.[0-9].sql' -delete

# Find files of 6.0 series (excluding anything above 6.1)
find . -type f -regex '\.\/6\.0\.[0-9]_to_6\.0\.[0-9].sql' -delete

There might be a more efficient way to find and delete files in one stroke, but we can use this in an Ansible task:

    - shell:
        cmd: |
          find . -type f -regex '\.\/[1-5]\.[0-9]\.[0-9]_to_[1-5]\.[0-9]\.[0-9].sql' -delete
          find . -type f -regex '\.\/6\.0\.[0-9]_to_6\.0\.[0-9].sql' -delete
        chdir: path/to/sql

CodePudding user response:

For example, given the files

shell> tree test-482
test-482
├── 5.0.1_to_5.0.4.sql
├── 6.0.1_to_6.0.2.sql
└── 7.0.1_to_7.0.9.sql

Find the files

    - find:
        path: test-482
        recurse: true
      register: result

gives the result

  result.files|map(attribute='path')|list:
  - test-482/5.0.1_to_5.0.4.sql
  - test-482/6.0.1_to_6.0.2.sql
  - test-482/7.0.1_to_7.0.9.sql

Parse the attributes and create the dictionary

    - set_fact:
        files_from_to: "{{ dict(_files|zip(_from_to)) }}"
      vars:
        _files: "{{ result.files|map(attribute='path')|list }}"
        _names: "{{ _files|map('basename')|map('splitext')|map('first')|list }}"
        _from_to: "{{ _names|map('regex_replace', _regex, _replace)|map('from_yaml')|list }}"
        _regex: "^(.*)_to_(.*)$"
        _replace: '{"from": "\1", "to": "\2"}'

gives

  files_from_to:
    test-482/5.0.1_to_5.0.4.sql:
      from: 5.0.1
      to: 5.0.4
    test-482/6.0.1_to_6.0.2.sql:
      from: 6.0.1
      to: 6.0.2
    test-482/7.0.1_to_7.0.9.sql:
      from: 7.0.1
      to: 7.0.9

Use the test version to select the files, e.g.

    - name: Anything higher then 6.1.0
      set_fact:
        files_del: "{{ files_from_to|dict2items|
                       selectattr('value.to', 'version', _version, 'gt')|
                       map(attribute='key')|list }}"
      vars:
        _version: '6.1.0'

gives

  files_del:
  - test-482/7.0.1_to_7.0.9.sql

or,

    - name: Anything lower then 6.0.2
      set_fact:
        files_del: "{{ files_from_to|dict2items|
                       selectattr('value.from', 'version', _version, 'lt')|
                       map(attribute='key')|list }}"
      vars:
        _version: '6.0.2'

gives

  files_del:
  - test-482/5.0.1_to_5.0.4.sql
  - test-482/6.0.1_to_6.0.2.sql

Debug the dictionary step by step

    - debug:
        var: _files
      vars:
        _files: "{{ result.files|map(attribute='path')|list }}"

    - debug:
        var: _names
      vars:
        _files: "{{ result.files|map(attribute='path')|list }}"
        _names: "{{ _files|map('basename')|map('splitext')|map('first')|list }}"

    - debug:
        var: _from_to
      vars:
        _files: "{{ result.files|map(attribute='path')|list }}"
        _names: "{{ _files|map('basename')|map('splitext')|map('first')|list }}"
        _from_to: "{{ _names|map('regex_replace', _regex, _replace)|map('from_yaml')|list }}"
        _regex: "^(.*)_to_(.*)$"
        _replace: '{"from": "\1", "to": "\2"}'

    - debug:
        var: _files|zip(_from_to)
      vars:
        _files: "{{ result.files|map(attribute='path')|list }}"
        _names: "{{ _files|map('basename')|map('splitext')|map('first')|list }}"
        _from_to: "{{ _names|map('regex_replace', _regex, _replace)|map('from_yaml')|list }}"
        _regex: "^(.*)_to_(.*)$"
        _replace: '{"from": "\1", "to": "\2"}'

give

TASK [debug] ***********************************************
ok: [localhost] => 
  _files:
  - test-482/5.0.1_to_5.0.4.sql
  - test-482/6.0.1_to_6.0.2.sql
  - test-482/7.0.1_to_7.0.9.sql

TASK [debug] ***********************************************
ok: [localhost] => 
  _names:
  - 5.0.1_to_5.0.4
  - 6.0.1_to_6.0.2
  - 7.0.1_to_7.0.9

TASK [debug] ***********************************************
ok: [localhost] => 
  _from_to:
  - from: 5.0.1
    to: 5.0.4
  - from: 6.0.1
    to: 6.0.2
  - from: 7.0.1
    to: 7.0.9

TASK [debug] ***********************************************
ok: [localhost] => 
  _files|zip(_from_to):
  - - test-482/5.0.1_to_5.0.4.sql
    - from: 5.0.1
      to: 5.0.4
  - - test-482/6.0.1_to_6.0.2.sql
    - from: 6.0.1
      to: 6.0.2
  - - test-482/7.0.1_to_7.0.9.sql
    - from: 7.0.1
      to: 7.0.9
  •  Tags:  
  • Related