You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查找目录下最新文件并拆分文件名与版本号

问题:提取目录下最新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的问题

  1. 变量格式错误:latest_files是列表类型,直接传入shell会变成类似['/path/to/file.tar']的格式,shell无法正确解析这种带方括号和引号的内容。
  2. 文件名拆分逻辑遗漏后缀处理:原shell命令没有先去除.tar后缀,导致拆分结果异常,最终输出为空。
  3. 最新文件筛选逻辑冗余:原逻辑按目录去重保留每个目录的最新文件,但需求是获取整个目录下的最新文件,直接取排序后的第一个文件即可。

修正后的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

修正说明

  1. 获取最新文件:对find返回的文件列表按修改时间倒序排序,直接取第一个元素的路径,即为整个目录下的最新文件。
  2. 清理文件名:用basename去除路径,再通过正则regex_replace('\\.tar$', '')去掉.tar后缀,得到纯文件名部分。
  3. 拆分名称与版本:
    • 用regex_replace('_\\d+\\..*$', '')匹配最后一个下划线开头的版本段(以数字开头,包含点号),替换为空得到文件名称部分。
    • 用捕获组.*_(\\d+\\..*)$提取版本号部分,通过\\1引用捕获的内容得到版本号。

内容的提问来源于stack exchange,提问作者harsha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 05:35:28