如何在Ansible中按自定义扩展偏好排序并过滤文件列表
无需自定义过滤器的实现方案
可以通过Ansible原生过滤器组合实现需求,核心思路是先过滤匹配指定扩展名的文件,再为每个文件标记优先级索引,最后按索引排序。以下是具体实现步骤:
步骤1:定义扩展名优先级列表
先明确你的优先级规则,比如:
- name: Set extension priority order ansible.builtin.set_fact: ext_priority: ['deb', 'appimage', 'tar.gz', '']
空字符串对应无扩展名的可执行文件。
步骤2:过滤符合条件的文件
用正则匹配筛选出仅包含优先级列表中扩展名的文件,同时处理多后缀(如tar.gz)和无后缀的情况:
- name: Filter assets to match priority extensions ansible.builtin.set_fact: filtered_assets: >- {{ asset_list | select('search', '^(?:.*\.(?:' ~ ext_priority | reject('equalto', '') | join('|') | regex_escape ~ '))|(?:^[^.]+$)') | list }}
regex_escape:处理扩展名中的特殊字符(如tar.gz里的.),避免正则语法错误- 正则逻辑:匹配「以指定扩展名结尾」或「无任何
.的文件」
步骤3:为文件标记优先级索引
循环过滤后的文件,提取其扩展名并匹配优先级列表中的索引,为每个文件附加排序依据:
- name: Attach priority index to each asset ansible.builtin.set_fact: assets_with_priority: >- {{ assets_with_priority | default([]) + [ { 'name': item, 'priority': ext_priority.index( # 提取扩展名(去掉开头的`.`),无扩展名则返回空字符串 item | regex_search('\.(?:' ~ ext_priority | reject('equalto', '') | join('|') | regex_escape ~ ')$') | regex_replace('^\.', '') | default('') ) } ] }} loop: "{{ filtered_assets }}"
步骤4:按优先级排序并提取文件名
基于优先级索引排序,最后提取原文件名得到结果:
- name: Sort assets by priority ansible.builtin.set_fact: sorted_assets: >- {{ assets_with_priority | sort(attribute='priority') | map(attribute='name') | list }}
完整示例Playbook
- name: Process asset list (filter and sort by extension priority) hosts: localhost gather_facts: false vars: asset_list: - artifact_amd64.tar.gz - artifact_amd64.tar.gz.sbom - artifact_arm64.tar.gz - artifact.deb - artifact.appimage - artifact_amd64 - artifact_amd64.sha256sum tasks: - name: Set extension priority order ansible.builtin.set_fact: ext_priority: ['deb', 'appimage', 'tar.gz', ''] - name: Filter assets to match priority extensions ansible.builtin.set_fact: filtered_assets: >- {{ asset_list | select('search', '^(?:.*\.(?:' ~ ext_priority | reject('equalto', '') | join('|') | regex_escape ~ '))|(?:^[^.]+$)') | list }} - name: Attach priority index to each asset ansible.builtin.set_fact: assets_with_priority: >- {{ assets_with_priority | default([]) + [ { 'name': item, 'priority': ext_priority.index( item | regex_search('\.(?:' ~ ext_priority | reject('equalto', '') | join('|') | regex_escape ~ ')$') | regex_replace('^\.', '') | default('') ) } ] }} loop: "{{ filtered_assets }}" - name: Sort assets by priority ansible.builtin.set_fact: sorted_assets: >- {{ assets_with_priority | sort(attribute='priority') | map(attribute='name') | list }} - name: Print sorted result ansible.builtin.debug: var: sorted_assets
执行结果
最终sorted_assets的输出为:
[ "artifact.deb", "artifact.appimage", "artifact_amd64.tar.gz", "artifact_arm64.tar.gz", "artifact_amd64" ]
完全符合优先级排序要求,且自动过滤了不匹配的文件(如.sbom、.sha256sum后缀的文件)。
内容的提问来源于stack exchange,提问作者Darth Banana
相关产品推荐
相关产品推荐

