在 Ansible 中,如何在文件末尾添加一段文本,并在标记前添加一个空行?

问题描述 投票:0回答:4

我有一个剧本,如下所示:

- hosts: localhost
  tasks:
    - name: update a file
      blockinfile:
        dest: /tmp/test
        block: |
          line 1
          line 2

运行剧本后,文件

/tmp/test
变为:

a # this is the end line of the original file
# BEGIN ANSIBLE MANAGED BLOCK
line 1
line 2
# END ANSIBLE MANAGED BLOCK

我想在标记“

# BEGIN ANSIBLE MANAGED BLOCK
”之前添加一个空行(换行符)以获得视觉效果。
最简单的方法是什么?最好在任务范围内,但欢迎任何想法。如果我重新定义标记,它将影响“
BEGIN
”和“
END
”标记。

ansible ansible-2.x
4个回答
4
投票

使用lineinfile。例如

- hosts: localhost
  tasks:
    - name: update a file
      blockinfile:
        dest: /tmp/test
        block: |
          line 1
          line 2
    - name: insert empty line before the marker
      lineinfile:
        dest: /tmp/test
        insertbefore: '^# BEGIN ANSIBLE MANAGED BLOCK$'
        line: ''

不幸的是,insertbefore 不适用于更多块。如果您坚持在块之间使用空行,则可能需要template模块。

尝试下面的剧本。不幸的是,EOF 没有按预期工作

shell> cat manage-block.yml
- name: "insert {{ my_marker }} in {{ my_dest }}"
  blockinfile:
    dest: "{{ my_dest }}"
    marker: "# {mark} ANSIBLE MANAGED BLOCK {{ my_marker }}"
    block: "{{ my_block }}"
- name: "insert empty line before {{ my_marker }}"
  lineinfile:
    dest: "{{ my_dest }}"
    insertbefore: '^# BEGIN ANSIBLE MANAGED BLOCK {{ my_marker }}'
    line: 'empty line'
  when: ansible_loop.first
- name: "insert empty line after EOF"
  lineinfile:
    dest: "{{ my_dest }}"
    insertafter: EOF
    line: 'empty line'
- hosts: localhost
  vars:
    my_blocks:
      /tmp/test:
        - my_marker: block001
          my_block: |
            line 1
            line 2
        - my_marker: block002
          my_block: |
            line 3
            line 4
  tasks:
    - include_tasks: manage-block.yml
      with_subelements:
        - "{{ my_blocks|dict2items }}"
        - value
      loop_control:
          extended: true
      vars:
        my_dest: "{{ item.0.key }}"
        my_marker: "{{ item.1.my_marker }}"
        my_block: "{{ item.1.my_block }}"

2
投票

重要警告:遗憾的是,这不是一个幂等任务。


如果您使用的是 Ansible 2.5 或更高版本,您可以更改

marker
marker_begin
marker_end

这是一个示例任务:

- blockinfile:
    dest: /tmp/test
    marker: '{mark} ANSIBLE MANAGED BLOCK'
    marker_begin: '\n# BEGIN' 
    marker_end: '# END'
    block: |
      line 1
      line 2

这将使用以下内容填充文件 /tmp/test

a
 
# BEGIN ANSIBLE MANAGED BLOCK
line 1
line 2
# END ANSIBLE MANAGED BLOCK

1
投票

如果您有一个如下所示的文件:

some line
foobar
some other line

并且您想在本示例中的模式“foobar”之前添加换行符,以下 ansible 代码将为您完成此操作:

- hosts: localhost
  gather_facts: no
  connection: local
  tasks:
    - name: update a file
      replace:
        dest: /tmp/foobar
        regexp: |
          (?mx)     # "m" lets ^ and $ match next to imbedded \n, x allows white space for readability
          (?<!\n\n) # a Zero-Length Assertion that it does not have an empty line already
          ^         # beginning of the line
          (foobar)  # match "foobar" and save it as \1, it could be "\#\ BEGIN\ ANSIBLE\ MANAGED\ BLOCK" if that is your pattern
          $         # end of line
        replace: "\n\\1" # add a newline before the matched pattern

并且它是幂等的,当模式不存在时,它不会在文件末尾添加换行符。


1
投票

目前无法将其作为一项任务来完成。但可以分为两个:

- blockinfile:
    dest: /tmp/test
    marker: "# {mark} ANSIBLE MANAGED BLOCK foo bar baz"
    block: |
      line 1
      line 2

- replace:
    dest: /tmp/test
    regexp: "(?<!\n\n)(# BEGIN ANSIBLE MANAGED BLOCK foo bar baz)"
    replace: '\n\1'           # or '\n\1\n' for padding before and after

与其他答案不同,它是幂等的,并且在多个块相继存在时起作用。 (正则表达式的详细信息此处。)

但如果

blockinfile
可以使用新选项来处理填充,那就太好了。


因此,我向存储库添加了一个功能请求。如果您想要此功能,请投票该问题。

© www.soinside.com 2019 - 2024. All rights reserved.