Ansible正则提取Cisco闪存文件名异常:仅获取最后一个文件
Cisco IOS闪存文件备份Ansible剧本问题排查
问题场景
我编写了用于备份Cisco设备IOS闪存文件的Ansible剧本,执行show flash:命令后尝试提取所有文件名到列表,但最终只提取到最后一个文件名。剧本代码如下:
--- - name: Backup Flash Files from Cisco Devices hosts: cisco gather_facts: no tasks: - name: List flash files ios_command: commands: - "show flash:" register: flash_files - name: Debug flash files output debug: var: flash_files.stdout_lines - name: Extract file names set_fact: files: "{{ flash_files.stdout_lines | select('search', '\\+00:00\\s+.*') | map('regex_replace', '^.*\\+00:00\\s+(.*)$', '\\1') | list }}" - name: Create directory on local delegate_to: localhost ansible.builtin.file: path: "/ios_backup/{{ inventory_hostname }}" state: directory - name: Copy flash files to local fetch: src: "flash:{{ item }}" dest: "/ios_backup/{{ inventory_hostname }}/" flat: yes loop: "{{ files }}"
已知flash_files.stdout_lines的输出行格式为:
<serial number> <timestamp> 00:00 <filename>
问题原因
stdout_lines结构误解:ios_command模块返回的stdout_lines是二维列表——外层列表对应每个执行的命令,内层列表才是该命令输出的每一行。直接对flash_files.stdout_lines做过滤操作,实际是在外层列表(仅包含一个元素,即所有行的列表)上处理,而非遍历每一行。- 正则表达式不匹配:正则中使用
\+00:00匹配带加号的时间后缀,但实际输出格式中是00:00(无加号),导致大部分行无法被匹配,仅最后一行(可能恰好包含+00:00)被提取。
解决方案
修改set_fact任务,先获取第一个命令的输出行列表(flash_files.stdout_lines[0]),同时调整正则匹配实际输出格式:
- name: Extract file names set_fact: files: "{{ flash_files.stdout_lines[0] | select('search', '00:00\\s+.*') | map('regex_replace', '^.*00:00\\s+(.*)$', '\\1') | list }}"
额外优化建议
如果show flash:输出中存在其他无关行(如表头、统计信息),可以进一步缩小匹配范围,确保只提取符合格式的文件名行:
- name: Extract file names set_fact: files: "{{ flash_files.stdout_lines[0] | select('match', '^\\d+\\s+\\S+\\s+00:00\\s+.*') | map('regex_replace', '^\\d+\\s+\\S+\\s+00:00\\s+(.*)$', '\\1') | list }}"
内容的提问来源于stack exchange,提问作者mrin9san
相关产品推荐
相关产品推荐

