简体   繁体   English

ansible正则表达式替换所有匹配的string1,排除string2

[英]ansible regex replace all matching string1, exclude string2

I'd like to replace all instances of dogs with cats , except for those where the line has does not play with mice . 我想用cats代替dogs所有实例,除了那些does not play with micedogs以外。

My file contents looks like: 我的文件内容如下:

dogs:plays with mice
dogs:plays with mice
dogs:does not play with mice
dogs:plays with mice
dogs:plays with mice
dogs:does not play with mice
dogs:plays with mice

Below are the important bits to my ansible-playbook, to try achieve the desired result: 以下是我的ansible-playbook的重要内容,以尝试达到所需的结果:

  vars:
    file_to_update: /tmp/cats_dogs_file.txt
    exclude: "does not play with mice"
    from_name: "dogs"
    to_name: "cats"

  tasks:    

  - name: updates dogs to cats - excluding the necessary
    replace:
      path: "{{ file_to_update }}"
      regexp: "^{{ from_name }}(?! {{ exclude }})"
      replace: "{{ to_name }}"
    register: file_update_status

I expect the contents of the file to be changed as per the below: 我希望按照以下内容更改文件的内容:

cats:plays with mice
cats:plays with mice
dogs:does not play with mice
cats:plays with mice
cats:plays with mice
dogs:does not play with mice
cats:plays with mice

Instead I currently get all dogs changed to cats . 相反,我目前把所有的dogs变成了cats

The exclude is not being adhered to. 不遵守排除规则。

Maybe, here we could write an expression and find the parts of your desired output and replace them. 也许在这里,我们可以编写一个表达式,找到所需输出的各个部分并替换它们。 Maybe something similar to: 也许类似于:

(.+):(plays? with)\s(.+)

在此处输入图片说明

JavaScript Demo JavaScript示范

 const regex = /(.+):(plays? with)\\s(.+)/gm; const str = `dogs:plays with mice dogs:plays with mice dogs:does not play with mice dogs:plays with mice dogs:plays with mice dogs:does not play with mice dogs:plays with mice cats:plays with mice cats:plays with mice dogs:does not play with mice cats:plays with mice cats:plays with mice dogs:does not play with mice cats:plays with mice`; const subst = `cats:$2 $3`; // The substituted value will be contained in the result variable const result = str.replace(regex, subst); console.log('Substitution result: ', result); 

Python Test Python测试

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(.+):(plays? with)\s(.+)"

test_str = ("dogs:plays with mice\n"
    "dogs:plays with mice\n"
    "dogs:does not play with mice\n"
    "dogs:plays with mice\n"
    "dogs:plays with mice\n"
    "dogs:does not play with mice\n"
    "dogs:plays with mice\n\n"
    "cats:plays with mice\n"
    "cats:plays with mice\n"
    "dogs:does not play with mice\n"
    "cats:plays with mice\n"
    "cats:plays with mice\n"
    "dogs:does not play with mice\n"
    "cats:plays with mice")

subst = "cats:\\2 \\3"

# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 0, re.MULTILINE)

if result:
    print (result)

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

RegEx 正则表达式

If this wasn't your desired expression, you can modify/change your expressions in regex101.com . 如果这不是您想要的表达式,则可以在regex101.com中修改/更改表达式。

RegEx Circuit RegEx电路

You can also visualize your expressions in jex.im : 您还可以在jex.im中可视化表达式:

在此处输入图片说明

A simple solution would be to loop over the lines and conditionally exclude the lines that shall not be replaced. 一种简单的解决方案是在线路上循环并有条件地排除不应更换的线路。

The play below 下面的戏

tasks:
  - replace:
      path: "{{ file_to_update }}"
      regexp: "{{ item }}"
      replace: "{{ item|regex_replace(from_name, to_name) }}"
    with_lines: "cat {{ file_to_update }}"
    when: exclude not in item

gives (abridged): 给出(删节):

TASK [replace] 
******************************************************************************
changed: [localhost] => (item=dogs:plays with mice)
ok: [localhost] => (item=dogs:plays with mice)
skipping: [localhost] => (item=dogs:does not play with mice) 
ok: [localhost] => (item=dogs:plays with mice)
ok: [localhost] => (item=dogs:plays with mice)
skipping: [localhost] => (item=dogs:does not play with mice) 
ok: [localhost] => (item=dogs:plays with mice)

> cat cats_dogs_file.txt
cats:plays with mice
cats:plays with mice
dogs:does not play with mice
cats:plays with mice
cats:plays with mice
dogs:does not play with mice
cats:plays with mice

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM