如何在Ansible中按行首规则将文件内容插入到另一文件
按规则插入文件内容的Ansible解决方案
需求说明
要把/tmp/test1里不在/tmp/test2里的内容按下面的规则插到/tmp/test2:
- 字母开头的行:插到
/tmp/test2最后一条字母开头行的后面 @开头的行:插到/tmp/test2所有@开头行的最后面
原始文件内容
/tmp/test1:
argument1 argument2 @test1 @test2 @test3
/tmp/test2初始状态:
argument1.1 argument2192 @example @test2 @example1
- 处理后期望的
/tmp/test2:
argument1.1 argument2192 argument1 argument2 @example @test2 @example1 @test1 @test3
原Playbook的问题
你提供的Playbook有两个关键问题:
- 未做去重处理:会把
test1里已存在于test2的行(比如@test2)重复插入 - 插入位置逻辑错误:
insertafter: "^@*"的正则匹配逻辑完全不对,它会匹配所有行,根本无法区分两种类型的行,自然插不到正确位置
正确的Playbook实现
- name: 按规则插入文件内容 hosts: localhost tasks: - name: 读取/tmp/test1的内容 command: cat /tmp/test1 register: test1_content - name: 读取/tmp/test2的内容 command: cat /tmp/test2 register: test2_content - name: 筛选test1中独有的行(不在test2里的内容) set_fact: unique_lines: "{{ test1_content.stdout_lines | difference(test2_content.stdout_lines) }}" - name: 将独有行按规则分类 set_fact: alpha_lines: "{{ unique_lines | select('match', '^[a-zA-Z].*') | list }}" at_lines: "{{ unique_lines | select('match', '^@.*') | list }}" - name: 插入字母开头的行到对应位置 lineinfile: path: /tmp/test2 line: "{{ item }}" insertafter: "^[a-zA-Z].*" state: present loop: "{{ alpha_lines }}" - name: 插入@开头的行到对应位置 lineinfile: path: /tmp/test2 line: "{{ item }}" insertafter: "^@.*" state: present loop: "{{ at_lines }}"
方案解释
- 读取与去重:通过
difference过滤器筛选出test1独有的行,避免重复插入已存在的内容 - 行分类:用正则匹配将独有行拆分为字母开头和
@开头两类,方便分别处理 - 精准插入:
- 字母开头的行:用
insertafter: "^[a-zA-Z].*"定位到test2中最后一条同类型行的末尾插入 @开头的行:用insertafter: "^@.*"定位到test2中最后一条@类型行的末尾插入
- 字母开头的行:用
内容的提问来源于stack exchange,提问作者medisamm
相关产品推荐
相关产品推荐

