Ansible如何对含整数的字符串进行非字典序排序?
Ansible 按版本号正确筛选最高/最低版本文件的解决方案
核心思路
放弃字典序排序,通过正则提取文件名中的版本号数字(单段或多段),将其转换为整数/整数列表后进行数值排序,再对应回原文件路径,即可精准筛选出最高或最低版本的文件。
单段版本号场景(如script_v9.sh、script_v10.sh)
1. 获取目标文件列表
先用find模块扫描目标目录,匹配符合命名规则的脚本文件:
- name: 扫描目标目录下的版本化脚本 ansible.builtin.find: path: /your/target/directory patterns: "script_v*.sh" file_type: file register: script_files
2. 提取版本号并关联文件路径
通过正则提取版本号的整数部分,将版本号与原文件路径配对成二维列表:
- name: 提取版本号并关联文件路径 ansible.builtin.set_fact: script_version_pairs: "{{ script_files.files | map(attribute='path') | map('regex_replace', '^.*script_v(\\d+)\\.sh$', '\\1') | zip(script_files.files | map(attribute='path')) | list }}"
注:根据实际文件名格式调整正则表达式,比如文件名是
app_v123.sh,就把正则改成^.*app_v(\\d+)\\.sh$。
3. 筛选最高/最低版本文件
利用sort过滤器,以版本号的整数值为排序依据,再选取对应结果:
- 筛选最高版本:
- name: 确定最高版本脚本路径 ansible.builtin.set_fact: latest_script_path: "{{ script_version_pairs | sort(key=lambda x: x[0] | int) | last | last }}"
- 筛选最低版本:
- name: 确定最低版本脚本路径 ansible.builtin.set_fact: oldest_script_path: "{{ script_version_pairs | sort(key=lambda x: x[0] | int) | first | last }}"
多段版本号场景(如script_v1.2.3.sh、script_v1.10.0.sh)
如果版本号是语义化格式(多段数字),可将版本号拆分为整数列表后排序:
1. 处理版本号为整数列表
- name: 处理多段版本号与文件路径的配对 ansible.builtin.set_fact: semver_script_pairs: "{{ script_files.files | map(attribute='path') | map('regex_replace', '^.*script_v([\\d.]+)\\.sh$', '\\1') | map('split', '.') | map('map', 'int') | zip(script_files.files | map(attribute='path')) | list }}"
2. 筛选最高/最低版本
由于Python支持列表的字典序比较([1,10,0] > [1,2,3]),直接用列表作为排序key即可:
- 最高版本:
- name: 确定最高语义化版本脚本路径 ansible.builtin.set_fact: latest_semver_script: "{{ semver_script_pairs | sort(key=lambda x: x[0]) | last | last }}"
- 最低版本:
- name: 确定最低语义化版本脚本路径 ansible.builtin.set_fact: oldest_semver_script: "{{ semver_script_pairs | sort(key=lambda x: x[0]) | first | last }}"
注意事项
- 确保正则表达式能精准匹配文件名中的版本号部分,避免提取错误;
- 如果文件名中存在非数字的版本标识(如beta、rc),需额外处理后再排序,比如将
beta映射为低于正式版的数值。
内容的提问来源于stack exchange,提问作者Viscosity
相关产品推荐
相关产品推荐

