Ansible中如何基于最低公共目录生成新路径列表?
解决Ansible中路径列表的最低公共目录提取问题
问题场景
现有路径列表:
the_list: - /tmp/another/six - /tmp/another/five - /hi/ho/one/abc - /hi/ho/two/abc - /something
需要将共享最低公共父目录的路径合并,最终得到:
- /tmp/another - /hi/ho - /something
原方法问题分析
你尝试的the_list | map('dirname') | unique | min逻辑有误:map('dirname')仅提取每个路径的直接父目录,min则是取字典序最小的目录,无法实现按公共前缀分组并提取最低公共目录的需求。
解决方案
可以通过拆分路径段、分组公共前缀、重组路径的方式实现,以下是具体Playbook示例:
- name: 提取最低公共目录 hosts: localhost vars: the_list: - /tmp/another/six - /tmp/another/five - /hi/ho/one/abc - /hi/ho/two/abc - /something tasks: - name: 生成路径段列表并分组公共前缀 set_fact: grouped_paths: >- {% set path_segments = the_list | map('regex_replace', '^/', '') | map('split', '/') | list %} {% set groups = {} %} {% for segments in path_segments %} {% set current_prefix = [] %} {% for seg in segments %} {% set _ = current_prefix.append(seg) %} {% set prefix_str = '/' ~ '/'.join(current_prefix) %} {% if prefix_str not in groups %} {% set _ = groups.__setitem__(prefix_str, []) %} {% endif %} {% set _ = groups[prefix_str].append('/' ~ '/'.join(segments)) %} {% endfor %} {% endfor %} {% set valid_groups = groups | dict2items | selectattr('value', 'length', '>', 1) | list %} {% set single_paths = the_list | difference(valid_groups | sum(attribute='value', start=[])) %} {% set result = valid_groups | map(attribute='key') | list + single_paths %} {{ result | unique | sort }} - name: 打印结果 debug: var: grouped_paths
逻辑说明
- 拆分路径段:把每个路径去掉开头的
/后按/拆分,得到目录段列表 - 构建前缀映射:遍历每个路径的所有前缀(比如
/tmp/another/six的前缀包括/tmp、/tmp/another、/tmp/another/six),记录每个前缀对应的所有原路径 - 筛选有效分组:保留那些包含多个原路径的前缀(这些就是公共父目录),同时保留没有公共父目录的单个路径
- 合并结果:将有效前缀和单个路径合并,去重排序后得到最终列表
运行后输出的grouped_paths就是预期的结果列表。
内容的提问来源于stack exchange,提问作者Kevin C
相关产品推荐
相关产品推荐

