提问人:Carvainth 提问时间:10/10/2023 最后编辑:Carvainth 更新时间:10/11/2023 访问量:71
Ansible 替换正则表达式前后的多行
ansible replace multiples lines before and after regexp
问:
我正在使用 ansible tower 修改文件 .baroc,使用用户为正则表达式提交的变量。
对于exampe,这是要修改的文件:
AUTOMATION;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKBX';
commentaire='Automatic';
END
AUTOMATION;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKB42';
commentaire='Automatic';
END
AUTOMATION;
mc_service='.\* - PRE-PRODUCTION';
application_infogerant='toto|test';
mc_long_msg='eKB12345';
mc_host='';
mc_object_class='';
mc_object='';
mc_parameter='';
msg='';
groupe_affectation='EXPLOITATION_APPLICATIONS-TOTO';
commentaire='DT123';
END
\########################################################################################################################################################################
# TOTO - Affectation CA
\########################################################################################################################################################################
# TOTO - CTRLM
AUTOMATION;
mc_long_msg='eKB007';
ctm_application='test.';
ctm_group='';
ctm_jobname='';
ctm_datacenter='';
ctm_nodeid='';
ctm_msg='';
groupe_affectation='MCO_test';
commentaire='DT01';
END
AUTOMATION;
groupe_affectation='SUPPORT';
msg_exception='APPLI 4';
mc_long_msg='eKB007';
commentaire='Automatic';
END
在这个问题上,我想删除整个集团:
AUTOMATION;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKB42';
commentaire='Automatic';
END
这是我的剧本:
---
- name: Suppression d'un eKB au fichier Paperboy
hosts: localhost
become: yes
tasks:
- name: Vérifier si le eKB est bien présent ########Check if the eKB is present
lineinfile:
path: /exemple/of/a/PATH.baroc
line: "eKB042"
state: absent
check_mode: yes
register: presence
- name: Arrêter le playbook si le eKB n'est pas présent ########Stop the playbook if the eKB is absent
fail:
msg: "L'eKB042 n'est pas présent dans le fichier baroc."
when: presence.changed
- name: Copie du fichier baroc dans le old #Backup
ansible.builtin.copy:
src: /exemple/of/a/PATH.baroc
dest: /exemple/of/an/old/PATH.baroc.soway.{{ ansible_date_time.iso8601_basic }}
- name: Suppression de la règle au fichier PAPERBOY.baroc ########Delete bloc
ansible.builtin.replace:
path: /exemple/of/a/PATH.baroc
after: 'PAPERBOY(?:(?!PAPERBOY)(.|\\n))*eKB0031549'
before: 'END(?!(.|\\n)eKB0031549)'
regexp: '^.*(eKB042).$'
replace: '! '
...
问题是它开始了最后一次品尝而没有结束...... 我知道最后一个任务之前的所有内容都可以正常工作,因为我将其用于其他目的(添加行以制作新的 eKB),并且它工作正常。我认为问题出在我使用的正则表达式上......即使在 regex101 上也没关系。
因此,我愿意将集团从 AUTOMATION 删除到 END(我认为是最佳实践),或者如果太困难,请删除 eKB 之前的 3 行和 eKB 之后的 2 行;因为 playbook 将始终用于删除类似的自动化块。较长的块不会以这种方式删除,也不会具有相同的 eKB 编号
感谢您的帮助
答:
给定文件
shell> cat PATH.baroc
AUTOMATION;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKBX';
commentaire='Automatic';
END
PAPERBOY;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKB42';
commentaire='Automatic';
END
AUTOMATION;
mc_service='.\* - PRE-PRODUCTION';
application_infogerant='toto|test';
mc_long_msg='eKB12345';
mc_host='';
mc_object_class='';
mc_object='';
mc_parameter='';
msg='';
groupe_affectation='EXPLOITATION_APPLICATIONS-TOTO';
commentaire='DT123';
END
\########################################################################################################################################################################
# TOTO - Affectation CA
\########################################################################################################################################################################
# TOTO - CTRLM
AUTOMATION;
mc_long_msg='eKB007';
ctm_application='test.';
ctm_group='';
ctm_jobname='';
ctm_datacenter='';
ctm_nodeid='';
ctm_msg='';
groupe_affectation='MCO_test';
commentaire='DT01';
END
AUTOMATION;
groupe_affectation='SUPPORT';
msg_exception='APPLI 4';
mc_long_msg='eKB007';
commentaire='Automatic';
END
Q: Delete the entire bloc
PAPERBOY;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKB42';
commentaire='Automatic';
END
A: Read the file
- shell: cat PATH.baroc | egrep '.*;|END'
register: out
and parse the content
test: "{{ out.stdout|
split('END')|
select|
map('trim')|
map('regex_replace', ';', '')|
map('community.general.jc', 'ini') }}"
gives
test:
- AUTOMATION: ''
commentaire: Automatic
groupe_affectation: Test'
mc_long_msg: eKBX
msg_exception: APPLI 1
- PAPERBOY: ''
commentaire: Automatic
groupe_affectation: Test'
mc_long_msg: eKB42
msg_exception: APPLI 1
- AUTOMATION: ''
application_infogerant: toto|test
commentaire: DT123
groupe_affectation: EXPLOITATION_APPLICATIONS-TOTO
mc_host: ''
mc_long_msg: eKB12345
mc_object: ''
mc_object_class: ''
mc_parameter: ''
mc_service: .\* - PRE-PRODUCTION
msg: ''
- AUTOMATION: ''
commentaire: DT01
ctm_application: test.
ctm_datacenter: ''
ctm_group: ''
ctm_jobname: ''
ctm_msg: ''
ctm_nodeid: ''
groupe_affectation: MCO_test
mc_long_msg: eKB007
- AUTOMATION: ''
commentaire: Automatic
groupe_affectation: SUPPORT
mc_long_msg: eKB007
msg_exception: APPLI 4
Modify what you want and write the block
- debug:
msg: |
{% for i in test|reject('contains', 'PAPERBOY') %}
{% for k,v in i.items() %}
{% if loop.index == 1 %}
{{ k }};
{% else %}
{{ k }}='{{ v }}';
{% endif %}
{% endfor %}
END
{% endfor %}
gives
AUTOMATION;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKBX';
commentaire='Automatic';
END
AUTOMATION;
mc_service='.\* - PRE-PRODUCTION';
application_infogerant='toto|test';
mc_long_msg='eKB12345';
mc_host='';
mc_object_class='';
mc_object='';
mc_parameter='';
msg='';
groupe_affectation='EXPLOITATION_APPLICATIONS-TOTO';
commentaire='DT123';
END
AUTOMATION;
mc_long_msg='eKB007';
ctm_application='test.';
ctm_group='';
ctm_jobname='';
ctm_datacenter='';
ctm_nodeid='';
ctm_msg='';
groupe_affectation='MCO_test';
commentaire='DT01';
END
AUTOMATION;
groupe_affectation='SUPPORT';
msg_exception='APPLI 4';
mc_long_msg='eKB007';
commentaire='Automatic';
END
Example of a complete playbook for testing
- hosts: localhost
vars:
test: "{{ out.stdout|
split('END')|
select|
map('trim')|
map('regex_replace', ';', '')|
map('community.general.jc', 'ini') }}"
tasks:
- shell: cat PATH.baroc | egrep '.*;|END'
register: out
- debug:
var: test
- debug:
msg: |
{% for i in test|reject('contains', 'PAPERBOY') %}
{% for k,v in i.items() %}
{% if loop.index == 1 %}
{{ k }};
{% else %}
{{ k }}='{{ v }}';
{% endif %}
{% endfor %}
END
{% endfor %}
- copy:
dest: test.ini
content: |
{% for i in test|reject('contains', 'PAPERBOY') %}
{% for k,v in i.items() %}
{% if loop.index == 1 %}
{{ k }};
{% else %}
{{ k }}='{{ v }}';
{% endif %}
{% endfor %}
END
{% endfor %}
Q: Delete the entire bloc
AUTOMATION;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKBX';
commentaire='Automatic';
END
A: Put the blocks you want to delete into a list
blocks_del:
- |
AUTOMATION;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKBX';
commentaire='Automatic';
END
Convert the blocks to lines
lines_del: "{{ blocks_del|map('split')|map('join', ' ') }}"
lines: |
{% filter from_yaml %}
{% for i in test %}
{% for k,v in i.items() %}
{% if loop.index == 1 %}
- {{ k }};
{% else %}
{{ k }}='{{ v }}';
{% endif %}
{% endfor %}
END
{% endfor %}
{% endfilter %}
and write the difference between the lists
- debug:
msg: |
{% for i in lines|difference(lines_del) %}
{% for j in i|split('; ') %}
{{ j }}{% if not loop.last %};{% endif +%}
{% endfor %}
{% endfor %}
gives
msg: |-
PAPERBOY;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKB42';
commentaire='Automatic';
END
AUTOMATION;
mc_service='.\* - PRE-PRODUCTION';
application_infogerant='toto|test';
mc_long_msg='eKB12345';
mc_host='';
mc_object_class='';
mc_object='';
mc_parameter='';
msg='';
groupe_affectation='EXPLOITATION_APPLICATIONS-TOTO';
commentaire='DT123';
END
AUTOMATION;
mc_long_msg='eKB007';
ctm_application='test.';
ctm_group='';
ctm_jobname='';
ctm_datacenter='';
ctm_nodeid='';
ctm_msg='';
groupe_affectation='MCO_test';
commentaire='DT01';
END
AUTOMATION;
groupe_affectation='SUPPORT';
msg_exception='APPLI 4';
mc_long_msg='eKB007';
commentaire='Automatic';
END
Example of a complete playbook for testing
- hosts: localhost
vars:
test: "{{ out.stdout|
split('END')|
select|
map('trim')|
map('regex_replace', ';', '')|
map('community.general.jc', 'ini') }}"
blocks_del:
- |
AUTOMATION;
groupe_affectation='Test'';
msg_exception='APPLI 1';
mc_long_msg='eKBX';
commentaire='Automatic';
END
lines_del: "{{ blocks_del|map('split')|map('join', ' ') }}"
lines: |
{% filter from_yaml %}
{% for i in test %}
{% for k,v in i.items() %}
{% if loop.index == 1 %}
- {{ k }};
{% else %}
{{ k }}='{{ v }}';
{% endif %}
{% endfor %}
END
{% endfor %}
{% endfilter %}
tasks:
- shell: cat PATH.baroc | egrep '.*;|END'
register: out
- debug:
var: lines
- debug:
var: lines_del
- debug:
msg: |
{% for i in lines|difference(lines_del) %}
{% for j in i|split('; ') %}
{{ j }}{% if not loop.last %};{% endif +%}
{% endfor %}
{% endfor %}
You can simplify the code by creating a list of dictionaries you want to delete. For example,
blocks_del:
- AUTOMATION: ''
commentaire: Automatic
groupe_affectation: Test'
mc_long_msg: eKBX
msg_exception: APPLI 1
- PAPERBOY: ''
commentaire: Automatic
groupe_affectation: Test'
mc_long_msg: eKB42
msg_exception: APPLI 1
Then, you can directly iterate the difference
test|difference(blocks_del):
- AUTOMATION: ''
application_infogerant: toto|test
commentaire: DT123
groupe_affectation: EXPLOITATION_APPLICATIONS-TOTO
mc_host: ''
mc_long_msg: eKB12345
mc_object: ''
mc_object_class: ''
mc_parameter: ''
mc_service: .\* - PRE-PRODUCTION
msg: ''
- AUTOMATION: ''
commentaire: DT01
ctm_application: test.
ctm_datacenter: ''
ctm_group: ''
ctm_jobname: ''
ctm_msg: ''
ctm_nodeid: ''
groupe_affectation: MCO_test
mc_long_msg: eKB007
- AUTOMATION: ''
commentaire: Automatic
groupe_affectation: SUPPORT
mc_long_msg: eKB007
msg_exception: APPLI 4
评论