Ansible逐行读取文件并根据条件删除行

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

我正在尝试逐行读取文件并在满足某些条件时删除该行

示例输入文件:
abcd 美国东部时间 2036 年 10 月 25 日星期六 04:30:35
defg 2037 年 12 月 1 日星期二 18:59:59 EST
ghij 2022 年 6 月 17 日星期五 06:15:06 EDT

预期输出文件:
abcd 美国东部时间 2036 年 10 月 25 日星期六 04:30:35
defg 2037 年 12 月 1 日星期二 18:59:59

需要的逻辑是逐行读取文件并读取最后一个字段的年份。如果小于 2023,则删除文件中的该行。如果大于 2023,则保留该行。在此示例中,应删除最后一行,因为 2022 年小于 2023 年。

示例代码:

- name: read file   
  set_fact:
    root_certificate_content: "{{ lookup('file', /home/user/cert_cleanup/{{ output_file }}) }}"
  
- name: display   debug:
  year: "{{ root_certificate_content.split('\n') [-1]}}" 

- name: remove line
  << delete that line >>
  when:
   - year.value < 2023

我尝试了多种选择,但没有任何效果。第一步本身的错误

ansible ansible-2.x file-manipulation
1个回答
0
投票

给定文件

shell> cat /tmp/test.txt 
abcd Sat Oct 25 04:30:35 EDT 2036
defg Tue Dec 01 18:59:59 EST 2037
ghij Fri Jun 17 06:15:06 EDT 2022

获取文件内容

  content: "{{ lookup('file', output_file) }}"

分割线,创建年份列表,并根据年份和线创建字典

  lines: "{{ content.splitlines()|map('split') }}"
  years: "{{ lines|map('last')|map('int') }}"
  lines_year: "{{ dict(years|zip(lines)) }}"

给予

  lines_year:
    2022: [ghij, Fri, Jun, '17', '06:15:06', EDT, '2022']
    2036: [abcd, Sat, Oct, '25', '04:30:35', EDT, '2036']
    2037: [defg, Tue, Dec, '01', '18:59:59', EST, '2037']

拒绝2023年以上的线路加入线路

  lines_2023: "{{ lines_year|dict2items|
                  rejectattr('key', 'lt', 2023)|
                  map(attribute='value')|map('join', ' ') }}"

给予

  lines_2023:
  - abcd Sat Oct 25 04:30:35 EDT 2036
  - defg Tue Dec 01 18:59:59 EST 2037

写文件

     - copy:
         dest: "{{ output_file }}"
         content: |
           {% for line in  lines_2023 %}
           {{ line }}
           {% endfor %}

完整的测试剧本示例

shell> cat pb.yml
- hosts: all

  vars:

    lines: "{{ content.splitlines()|map('split') }}"
    years: "{{ lines|map('last')|map('int') }}"
    lines_year: "{{ dict(years|zip(lines)) }}"
    lines_2023: "{{ lines_year|dict2items|
                    rejectattr('key', 'lt', 2023)|
                    map(attribute='value')|map('join', ' ') }}"

  tasks:

     - set_fact:
         content: "{{ lookup('file', output_file) }}"
       run_once: true

     - debug:
         var: lines_year|to_yaml
     - debug:
         var: lines_2023

     - copy:
         dest: "{{ output_file }}"
         content: |
           {% for line in  lines_2023 %}
           {{ line }}
           {% endfor %}
       run_once: true
       delegate_to: localhost

给出运行选项--check --diff

shell> ansible-playbook -e output_file=/tmp/test.txt pb.yml -CD

PLAY [all] ************************************************************************************

TASK [set_fact] *******************************************************************************
ok: [localhost]

TASK [debug] **********************************************************************************
ok: [localhost] => 
  lines_year|to_yaml: |-
    2022: [ghij, Fri, Jun, '17', '06:15:06', EDT, '2022']
    2036: [abcd, Sat, Oct, '25', '04:30:35', EDT, '2036']
    2037: [defg, Tue, Dec, '01', '18:59:59', EST, '2037']

TASK [debug] **********************************************************************************
ok: [localhost] => 
  lines_2023:
  - abcd Sat Oct 25 04:30:35 EDT 2036
  - defg Tue Dec 01 18:59:59 EST 2037

TASK [copy] ***********************************************************************************
--- before: /tmp/test.txt
+++ after: /home/vlado/.ansible/tmp/ansible-local-16289938umqjl9j/tmpbav5odkq
@@ -1,3 +1,2 @@
 abcd Sat Oct 25 04:30:35 EDT 2036
 defg Tue Dec 01 18:59:59 EST 2037
-ghij Fri Jun 17 06:15:06 EDT 2022

changed: [localhost]

PLAY RECAP ************************************************************************************
localhost: ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

备注:

  • lookup 插件总是在本地主机上执行
  • 读写文件一次。设置
    run_once: true
  • 将文件写回本地主机。设置
    delegate_to: localhost
© www.soinside.com 2019 - 2024. All rights reserved.