Ansible Playbook如何过滤以feature/dev开头的目录?
问题:Ansible过滤以feature或dev开头的目录
我需要用Ansible列出/tmp路径下以feature或dev开头的目录(例如dev032623、dev、feature032623、feature_ron等),同时筛选出存在30天以上的目录。
尝试以下Playbook后,结果是列出了/tmp下所有符合年龄条件的目录,未按前缀过滤:
- name: List old directories find: paths: /tmp age: 30d file_type: directory register: result - name: Show result debug: msg: "{{ item[0] | select ('match','^(feature|dev)) }}" loop: "{{ result.files }}" loop_control: extended: yes label: "{{ ansible_loop.index0 }}"
错误原因分析
item[0]用法错误:result.files中的每个item是字典(包含path、name等字段),并非列表,item[0]无法获取正确的目录名。select过滤器误用:select是用来过滤列表的,单个字符串匹配应该用match/search过滤器,而非select。- 正则表达式不完整:原正则
^(feature|dev)缺少闭合逻辑,正确的前缀匹配正则应为^(feature|dev).*(匹配前缀后任意字符)。
解决方案
方法一:在find模块直接过滤(推荐)
利用find模块的patterns参数直接过滤目录名,减少后续处理步骤:
- name: List old directories starting with feature or dev find: paths: /tmp age: 30d file_type: directory patterns: ['^feature.*', '^dev.*'] use_regex: yes register: result - name: Show filtered result debug: msg: "{{ item.path }}" loop: "{{ result.files }}" loop_control: label: "{{ item.name }}"
方法二:在debug任务中条件过滤
保留原find结果,仅在输出时通过when条件筛选:
- name: List old directories find: paths: /tmp age: 30d file_type: directory register: result - name: Show filtered result debug: msg: "{{ item.path }}" loop: "{{ result.files }}" when: item.name is match('^(feature|dev).*') loop_control: label: "{{ item.name }}"
方法三:先过滤列表再循环
先将符合条件的目录筛选为新变量,再循环输出:
- name: List old directories find: paths: /tmp age: 30d file_type: directory register: result - name: Filter directories by prefix set_fact: filtered_dirs: "{{ result.files | selectattr('name', 'match', '^(feature|dev).*') | list }}" - name: Show filtered result debug: msg: "{{ item.path }}" loop: "{{ filtered_dirs }}" loop_control: label: "{{ item.name }}"
关键说明
- 若需匹配完整路径的前缀,可将
item.name改为item.path,正则调整为^/tmp/(feature|dev).*。 match要求字符串完全匹配正则,仅需前缀匹配时用search也可,但^(feature|dev).*搭配match更严谨。loop_control中设置label: "{{ item.name }}"可让循环输出更清晰,便于查看对应目录。
内容的提问来源于stack exchange,提问作者Linus
相关产品推荐
相关产品推荐

