如何查找目录下最新文件并拆分文件名与版本号
问题:提取目录下最新tar文件的名称与版本号
需求描述
我有一个目录,其中包含如der_azureData_Linux_x64_24.1.0.0.7.tar这类文件。需要找出该目录下的最新文件,并将文件名拆分为名称和版本号。
预期输出
name: der_azureData_Linux_x64 version: 24.1.0.0.7
尝试的Playbook
我尝试了以下Playbook,但无法正常获取文件名:
- hosts: localhost gather_facts: no tasks: - find: paths: "/root/ansible.temp/" patterns: "*.tar" recurse: yes register: files_matched - set_fact: latest_files: "{{ latest_files | default([]) + [item.path] }}" loop: "{{ files_matched.files | sort(attribute='mtime', reverse=true) }}" when: "item.path | dirname not in latest_files | default([]) | map('dirname')" ## # The loop_control is just there for validation purpose ## loop_control: label: "{{ '%Y-%m-%d %H:%M:%S' | strftime(item.mtime) }} {{ item.path }}" - debug: var: latest_files - name: check the directories and locations shell: | f = {{ latest_files }} # loop over each file in current directory name="${f%_*}" # trim from right to first '_' register: name - name: print values debug: msg: "filename {{ name.stdout }} "
当前输出
TASK [check the directories and locations] ************************** changed: [localhost] TASK [print values] ************************************************* ok: [localhost] => { "msg": "filename " }
问题分析与修正方案
原Playbook的问题
- 变量格式错误:
latest_files是列表类型,直接传入shell会变成类似['/path/to/file.tar']的格式,shell无法正确解析这种带方括号和引号的内容。 - 文件名拆分逻辑遗漏后缀处理:原shell命令没有先去除
.tar后缀,导致拆分结果异常,最终输出为空。 - 最新文件筛选逻辑冗余:原逻辑按目录去重保留每个目录的最新文件,但需求是获取整个目录下的最新文件,直接取排序后的第一个文件即可。
修正后的Playbook
- hosts: localhost gather_facts: no tasks: - name: 查找所有tar文件并按修改时间倒序排序 find: paths: "/root/ansible.temp/" patterns: "*.tar" recurse: yes register: files_matched - name: 获取最新的tar文件路径 set_fact: latest_file_path: "{{ files_matched.files | sort(attribute='mtime', reverse=true) | first | json_query('path') }}" - name: 提取文件名(去除路径和.tar后缀) set_fact: latest_file_name: "{{ latest_file_path | basename | regex_replace('\\.tar$', '') }}" - name: 拆分名称和版本号 set_fact: file_info: name: "{{ latest_file_name | regex_replace('_\\d+\\..*$', '') }}" version: "{{ latest_file_name | regex_replace('.*_(\\d+\\..*)$', '\\1') }}" - name: 输出结果 debug: var: file_info
修正说明
- 获取最新文件:对
find返回的文件列表按修改时间倒序排序,直接取第一个元素的路径,即为整个目录下的最新文件。 - 清理文件名:用
basename去除路径,再通过正则regex_replace('\\.tar$', '')去掉.tar后缀,得到纯文件名部分。 - 拆分名称与版本:
- 用
regex_replace('_\\d+\\..*$', '')匹配最后一个下划线开头的版本段(以数字开头,包含点号),替换为空得到文件名称部分。 - 用捕获组
.*_(\\d+\\..*)$提取版本号部分,通过\\1引用捕获的内容得到版本号。
- 用
内容的提问来源于stack exchange,提问作者harsha
相关产品推荐
相关产品推荐

