Ansible 2.5.5 — атрибут » до «в модуле» заменить » не работает

#regex #ansible #ansible-2.x #regexp-replace

Вопрос:

Я пытаюсь заменить только первое вхождение после определенной строки. Однако ansible всегда будет соответствовать всем вхождениям. Вот файл:

Вот моя возможная задача:

     - name: Update minPoolSize for CWTxDataSource dataSource
      replace:
        dest: "{{ op_db_path }}"
        after: ".*CWTxDataSourceXA"
        regexp: "^.*minPoolSize=.*$"
        replace: '        <connectionManager maxPoolSize="750" minPoolSize="20" />'
        backup: yes
 
     <dataSource jndiName="CWTxDataSource">
        <connectionManager maxPoolSize="750" minPoolSize="1" />
    </dataSource>

    <dataSource jndiName="UMDataSource">
        <connectionManager maxPoolSize="750" minPoolSize="1" />
    </dataSource>
 

в приведенном выше примере оба connectionManager тега будут обновлены, что не является желаемым поведением? Как я могу обновить свой regexp , чтобы обновить только первое совпадение?? Я попробовал before опцию в replace модуле в качестве обходного пути, но по какой-то причине это не сработало для меня.

Комментарии:

1. реальный ответ на этот вопрос — использовать xml: то, что было разработано для работы со структурированными данными. Тем не менее, вы уже пробовали использовать before: его для дальнейшего ограничения пространства поиска?

2. Я попробую xml , спасибо! да, насчет before выбора.

3. Поскольку xml он зависит от lxml модуля pip на целевых виртуальных машинах, что не оптимально для моего случая: "msg": "The xml ansible module requires the lxml python library installed on the managed machine"

4. Тогда я бы предположил, что у вас есть два вонючих варианта: slurp: (или fetch: ) файл в узел управления, мутировать его, используя xml: , как задумано, затем вернуть его обратно в управляемый узел; или прочитать файл в память, удалить новые строки, чтобы шаблон был CWTxDataSource"(. ?) minPoolSize="1" и исправить его таким образом

5. спасибо, что откликнулись! Я понимаю, я имею в виду, что если регулярное выражение просто работает на соответствие первому вхождению, я бы просто использовал его, но не смог заставить его соответствовать только первому вхождению.

Ответ №1:

Я нашел следующую строку в ansible docs:

 # Prior to Ansible 2.7.10, using before and after in combination did the opposite of what was intended.
 

поэтому для того, чтобы я мог использовать after before их в качестве обходного пути, мне пришлось изменить их значения:

     - name: Update minPoolSize for CWTxDataSource dataSource
      # after / before values are reversed in ansible < 2.7
      replace:
        path: "{{ op_db_path }}"
        before: 'jndiName="CWTxDataSource"'
        after: "</dataSource>"
        regexp: 'minPoolSize="d "'
        replace: 'minPoolSize="{{ CWTxDS_minPoolSize }}"'
 

обратите after before внимание, что значения на самом деле не имеют смысла, но это работает!