Ansible匹配指定目录模式、保留最新3个版本删除其余版本实现问题
问题解决方法
你需要调整两处核心逻辑即可实现需求:
- 修正正则匹配规则,避免误匹配不符合版本号规则的目录
- 修复变量缩进错误,保证配置参数能被正确读取
修正后的完整代码
--- - name: 匹配目录并保留最新3个版本删除其余版本 hosts: localhost connection: local vars: base_dir: "/opt/repo/" artifacts: - "subject-mapper" - "artemis-margin-api" tasks: - name: 匹配符合规则的候选版本目录 become: yes find: paths: "{{ base_dir }}/{{ item }}" patterns: - "{{ item }}-[0-9]+\\.[0-9]+\\.[0-9]+$" use_regex: yes recurse: no file_type: directory loop: "{{ artifacts }}" register: output - debug: msg: "{{ output }}" - name: 过滤保留最新3个版本,其余版本加入待删列表 set_fact: # 按修改时间升序排列,旧版本在前,排除最后3个最新版本,剩余目录加入待删列表 files_to_delete: "{{ (files_to_delete|default([])) + (item['files'] | sort(attribute='mtime', reverse=False))[:-3] }}" loop: "{{ output['results'] }}" - debug: msg: "{{ files_to_delete }}" - name: 删除待删列表内的目录 file: path: "{{ item.path }}" state: absent loop: "{{ files_to_delete }}" when: confirm|default(false)|bool register: output_delete - debug: msg: "{{ output_delete }}"
关键改动说明
- 修正了
vars块下变量的缩进错误,原代码中base_dir、artifacts缩进不符合YAML规范,会导致变量读取失败 - 修正了版本号匹配正则,将原
.转义为\\.(YAML中需要二次转义),同时将*改为+保证版本号各段至少有一位数字,避免误匹配不符合规则的目录 - 显式声明排序的
reverse=False参数,明确按修改时间升序排列,确保最后3个元素是最新的版本,不会出现排序方向错误导致误删
如果你需要按版本号大小排序而非修改时间,只需要将排序逻辑替换为提取版本号后排序即可:
files_to_delete: "{{ (files_to_delete|default([])) + (item['files'] | sort(attribute='path' | split(item ~ '-') | last | version_sort))[:-3] }}"
内容的提问来源于stack exchange,提问作者S G
相关产品推荐
相关产品推荐

