Ansible执行PowerShell时如何过滤Format-Hex的stdout仅保留纯十六进制数据行
可直接落地的两种适配方案
方案1:PowerShell层直接提取目标格式(稳定性最高)
现在你拿到的格式化文本,本质是PowerShell把Format-Hex的返回对象渲染成人类可读的展示效果,其实Format-Hex本身返回的是结构化对象,自带每行的十六进制字节数组字段,完全没必要等输出成纯文本再做切割。
直接调整win_shell里的命令,适配PowerShell 5环境的写法:
Format-Hex -Path C:\test.txt | ForEach-Object { $_.Bytes -join ' ' }
跑完之后recorder收集到的stdout直接就是你要的纯十六进制行——没有开头的列头、没有行首的偏移地址、没有行尾的ASCII映射内容,完全匹配预期输出。
这里要提一下你之前写的示例代码的小问题:register: recorder被写在了win_shell的多行命令字符串内部,实际执行的时候这部分会被当成PowerShell命令运行,直接报错。需要把register调整到和win_shell同级的任务缩进位置,正确的任务写法:
- name: 读取文件的十六进制内容 win_shell: | Format-Hex -Path C:\test.txt | ForEach-Object { $_.Bytes -join ' ' } register: recorder - name: 查看过滤后的结果 debug: msg: "{{ recorder.stdout_lines }}"
方案2:保留原有Format-Hex命令,在Ansible层做文本过滤
如果不想改动原来的win_shell执行逻辑,需要拿到完整原始输出后再处理,可以用Ansible内置的文本插件通过正则提取目标段:
整体逻辑分两步:先过滤掉开头的列头、空行,只保留带8位偏移地址的有效数据行;再通过正则把每行里的偏移地址、末尾ASCII映射内容切掉,只保留中间的纯十六进制字节段。
对应的debug配置写法:
- name: 过滤提取纯十六进制内容 debug: msg: >- {{ recorder.stdout_lines | select('regex', '^[0-9A-Fa-f]{8}\s+(([0-9A-Fa-f]{2}\s+){1,16})') | map('regex_replace', '^[0-9A-Fa-f]{8}\s+(([0-9A-Fa-f]{2}\s+)+?)\s+.*$', '\1') | map('trim') }}
这套正则兼容最后一行字节数不足16个的边界情况,不会漏匹配文件末尾的非满行数据,处理完的输出和方案1效果完全一致。
内容的提问来源于stack exchange,提问作者CH06
相关产品推荐
相关产品推荐

