以迭代方式删除目录中的文件



我正在使用ansible将文件从docker容器复制到文件夹中。我想根据我正在下载的容器版本删除不需要的那些。 我根本不是脚本编写者,但我做到了:

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

在我的 ansible 代码中,它看起来像这样:

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

如何获取输出并删除早于标注版本的文件(在上面的例子中,任何早于 6.1.0 的文件)?

文件结构实际上是6.0.1_to_6.0.2.sql等等。

例如,给定文件

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:
path: test-482
recurse: true
register: 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

解析属性并创建字典

- set_fact:
files_from_to: "{{ dict(_files|zip(_from_to)|list) }}"
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"}'

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

使用测试版本选择文件,例如

- 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'

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

- 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'

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

逐步调试字典

- 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)|list
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"}'

_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
_names:
- 5.0.1_to_5.0.4
- 6.0.1_to_6.0.2
- 7.0.1_to_7.0.9
_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
_files|zip(_from_to)|list:
- - 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

逐步调试所选内容

- debug:
msg: "{{ files_from_to|dict2items }}"
- debug:
msg: "{{ files_from_to|dict2items|
selectattr('value.to', 'version', _version, 'gt') }}"
vars:
_version: '6.1.0'
- debug:
msg: "{{ files_from_to|dict2items|
selectattr('value.to', 'version', _version, 'gt')|
map(attribute='key')|list }}"
vars:
_version: '6.1.0'

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

既然你标记了bash,这里有一种方法可以做到这一点。

Linux find 命令支持-regex匹配文件名,也支持删除文件。因此,我们可以使用它们来查找和删除文件,而无需迭代。

# 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

可能有一种更有效的方法可以一次查找和删除文件,但我们可以在 Ansible 任务中使用它:

- 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

最新更新