替换文件中的字符串,如果存在,使用 Ansible playbook。

huangapple go评论75阅读模式
英文:

Replace string in file, if exists with Ansible playbook

问题

我有一个文件,其中包含一个由多个空格分隔的字符串组成的单行:

```shell
$ cat /tmp/strings.txt
alpha beta gamma zeta omega

我的目标是检查 /tmp/strings.txt 中是否不存在字符串 delta,如果不存在,则在 gamma 字符串后面添加它:

$ cat /tmp/strings.txt
alpha beta gamma delta zeta omega

我认为以下解决方案可能是合适的:

- name: 检查是否存在 delta 字符串
  ansible.builtin.command: grep 'delta' /tmp/strings.txt | wc -l
  register: delta_string

- name: 添加 delta 字符串
  ansible.builtin.blockinfile:
    block: gamma delta
    path: /tmp/strings.txt
  when: delta_string.stdout == 0

这是否是 Ansible 中适当使用字符串替换的方式?不确定 ansible.builtin.blockinfile 块如何工作,它会在未找到时将 gamma delta 字符串插入文件中作为 gamma 的替换,还是将其添加到文件末尾?是否有一个不需要 when 检查的解决方案?


<details>
<summary>英文:</summary>

I have a file, containing a single line of multiple space separated strings:

```shell
$ cat /tmp/strings.txt
alpha beta gamma zeta omega

My goal is to check if delta string is not present inside /tmp/strings.txt, and if not, add it after gamma string:

$ cat /tmp/strings.txt
alpha beta gamma delta zeta omega

What I think would be a solution:

    - name: Check if delta string is present
      ansible.builtin.command: grep &#39;delta&#39; /tmp/strings.txt | wc -l
      register: delta_string

    - name: Add delta string
      ansible.builtin.blockinfile:
        block: gamma delta
        path: /tmp/strings.txt
      when: delta_string.stdout == 0

Is this a proper use of string replacements in Ansible? Not sure how ansible.builtin.blockinfile block works, will it insert the gamma delta string if is not found, as replacement for gamma, or will it add it at the end of file?

Is there a solution which does require a when check?

答案1

得分: 1

将双胞胎放入字典中,例如:

  twins:
    gamma: delta
    foo: bar

读取文件并拆分项目。声明变量

  strings: &quot;{{ out.content|b64decode|split() }}&quot;

以下任务

    - slurp:
        src: /tmp/strings.txt
      register: out

给出字符串列表

  strings: [alpha, beta, gamma, zeta, omega]

迭代 strings 并添加缺失的双胞胎

  update_str: |
    [
    {% for i in strings %}
    {% if i in twins and strings[loop.index]|d(None) != twins[i] %}
    {{ i }}, {{ twins[i] }},
    {% else %}
    {{ i }},
    {% endif %}
    {% endfor %}
    ]    

给出有效的YAML

  update_str: |-
    [
    alpha,
    beta,
    gamma, delta,
    zeta,
    omega,
    ]    

将字符串转换为列表

  update: &quot;{{ update_str|from_yaml }}&quot;

给出

  update: [alpha, beta, gamma, delta, zeta, omega]

连接项目并写入文件

    - copy:
        dest: /tmp/strings.txt
        content: &quot;{{ update|join(&#39; &#39;) }}&quot;

给出

shell&gt; cat /tmp/strings.txt 
alpha beta gamma delta zeta omega

用于测试的完整playbook示例

- hosts: localhost

  vars:

    twins:
      gamma: delta
      foo: bar

    strings: &quot;{{ out.content|b64decode|split() }}&quot;
    update_str: |
      [
      {% for i in strings %}
      {% if i in twins and strings[loop.index]|d(None) != twins[i] %}
      {{ i }}, {{ twins[i] }},
      {% else %}
      {{ i }},
      {% endif %}
      {% endfor %}
      ]      
    update: &quot;{{ update_str|from_yaml }}&quot;

  tasks:

    - slurp:
        src: /tmp/strings.txt
      register: out
    - debug:
        var: strings
    - debug:
        var: update_str
    - debug:
        var: update
    - copy:
        dest: /tmp/strings.txt
        content: &quot;{{ update|join(&#39; &#39;) }}&quot;

英文:

Put the twins into a dictionary, e.g.

  twins:
    gamma: delta
    foo: bar

Read the file and split the items. Declare the variable

  strings: &quot;{{ out.content|b64decode|split() }}&quot;

The task below

    - slurp:
        src: /tmp/strings.txt
      register: out

gives the list of the strings

  strings: [alpha, beta, gamma, zeta, omega]

Iterate strings and add the twins if missing

  update_str: |
    [
    {% for i in strings %}
    {% if i in twins and strings[loop.index]|d(None) != twins[i] %}
    {{ i }}, {{ twins[i] }},
    {% else %}
    {{ i }},
    {% endif %}
    {% endfor %}
    ]    

gives valid YAML

  update_str: |-
    [
    alpha,
    beta,
    gamma, delta,
    zeta,
    omega,
    ]    

Convert the string to the list

  update: &quot;{{ update_str|from_yaml }}&quot;

gives

  update: [alpha, beta, gamma, delta, zeta, omega]

Join the items and write the file

    - copy:
        dest: /tmp/strings.txt
        content: &quot;{{ update|join(&#39; &#39;) }}&quot;

gives

shell&gt; cat /tmp/strings.txt 
alpha beta gamma delta zeta omega

<hr>

<sup>

Example of a complete playbook for testing

- hosts: localhost

  vars:

    twins:
      gamma: delta
      foo: bar

    strings: &quot;{{ out.content|b64decode|split() }}&quot;
    update_str: |
      [
      {% for i in strings %}
      {% if i in twins and strings[loop.index]|d(None) != twins[i] %}
      {{ i }}, {{ twins[i] }},
      {% else %}
      {{ i }},
      {% endif %}
      {% endfor %}
      ]      
    update: &quot;{{ update_str|from_yaml }}&quot;

  tasks:

    - slurp:
        src: /tmp/strings.txt
      register: out
    - debug:
        var: strings
    - debug:
        var: update_str
    - debug:
        var: update
    - copy:
        dest: /tmp/strings.txt
        content: &quot;{{ update|join(&#39; &#39;) }}&quot;

</sup>

答案2

得分: 0

根据您的描述,我理解您希望有一个仅包含“text”一行的文件。

由于Ansible是一种配置管理工具,您只需要声明所需的状态即可。无需进行任何检查,如果满足条件则插入(否则)的构造。

对于输入文件

~/test$ cat strings.txt
alpha beta gamma zeta omega

一个最小的示例playbook如下:

---
- hosts: localhost
  become: false
  gather_facts: false

  tasks:

  - name: 确保lineinfile处于所需状态
    lineinfile:
      path: strings.txt
      line: alpha beta gamma delta zeta omega
      regexp: '^alpha' # 或者甚至 '^alpha beta gamma zeta omega'

将会生成一个输出文件

~/test$ cat strings.txt
alpha beta gamma delta zeta omega

更多文档

也有可能会奏效

英文:

From your description I understand that you like to have a file with a single line of "text" only.

Since Ansible is a Configuration Management Tool with which you declare the Desired State, that is all what you would need to do. There is no need for any CHECK IF THEN INSERT (ELSE) WHEN contruct.

For an input file of

~/test$ cat strings.txt
alpha beta gamma zeta omega

a minimal example playbook

---
- hosts: localhost
  become: false
  gather_facts: false

  tasks:

  - name: Make sure lineinfile is in Desired State
    lineinfile:
      path: strings.txt
      line: alpha beta gamma delta zeta omega
      regexp: &#39;^alpha&#39; # or even &#39;^alpha beta gamma zeta omega&#39;

will result into an output file

~/test$ cat strings.txt
alpha beta gamma delta zeta omega

Further Documentation

Most likely would work too

huangapple
  • 本文由 发表于 2023年1月9日 15:10:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75054098.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定