从 "stdout" 或 "stdout_lines" 中获取准确的数据,并输出准确的单词

Get exactly data from "stdout" or "stdout_lines" with exact words of output

我有任务

- name: DELEGATED ADMIN ACCOUNTS - check, get and send to the file domain.list
  shell: /opt/zimbra/bin/zmprov -l gaaa -v zimbraIsDelegatedAdminAccount

完成这个任务后我得到了输出

changed: [Shrrah] => {
    "changed": true,
    "cmd": [
        "sh",
        "/home/information_domain.sh"
    ],
    "delta": "0:00:02.495922",
    "end": "2022-03-29 10:25:16.936051",
    "invocation": {
        "module_args": {
            "_raw_params": "sh /home/information_domain.sh",
            "_uses_shell": false,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true,
            "warn": false
        }
    },
    "msg": "",
    "rc": 0,
    "start": "2022-03-29 10:25:14.440129",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "# name admin@shrrah.esquimail.com\nzimbraIsDelegatedAdminAccount: FALSE\n\n# name prueba5@prueba5.com\n\n# name prueba7@prueba7.com\nzimbraIsDelegatedAdminAccount: TRUE\n\n# name prueba9@prueba9.com",
    "stdout_lines": [
        "# name admin@shrrah.esquimail.com",
        "zimbraIsDelegatedAdminAccount: FALSE",
        "",
        "# name prueba5@prueba5.com",
        "",
        "# name prueba7@prueba7.com",
        "zimbraIsDelegatedAdminAccount: TRUE",
        "",
        "# name prueba9@prueba9.com"
    ]
}

我需要使用 n# name prueba7@prueba7.com\nzimbraIsDelegatedAdminAccount: TRUE"stdout""stdout_lines" 获取数据,格式为:

prueba7@prueba7.com zimbraIsDelegatedAdminAccount: TRUE

prueba7@prueba7.com
zimbraIsDelegatedAdminAccount: TRUE

并将其发送到 file.txt。行数可以不同(一个或多个具有域的用户)。

我不知道该怎么做,这可能吗?如果你知道,你能帮忙提供建议吗?谢谢!

您可以查看 debug – Print statements during execution, Using Variables and Return Values

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

  vars:
    RESULT:
      STDOUT_LINES:
        - "# name admin@shrrah.esquimail.com"
        - "zimbraIsDelegatedAdminAccount: FALSE"
        - ""
        - "# name prueba5@prueba5.com"
        - ""
        - "# name prueba7@prueba7.com"
        - "zimbraIsDelegatedAdminAccount: TRUE"
        - ""
        - "# name prueba9@prueba9.com"

  tasks:

  - name: Show STDOUT_LINES
    debug:
      msg: "{{ RESULT.STDOUT_LINES }}"

结果只有

的输出
TASK [Show STDOUT_LINES] *****************
ok: [localhost] =>
  msg:
  - '# name admin@shrrah.esquimail.com'
  - 'zimbraIsDelegatedAdminAccount: FALSE'
  - ''
  - '# name prueba5@prueba5.com'
  - ''
  - '# name prueba7@prueba7.com'
  - 'zimbraIsDelegatedAdminAccount: TRUE'
  - ''
  - '# name prueba9@prueba9.com'

并且如果 Ansible Callback plugin 配置为 YAML 而不是 JSON。

要获取仅包含特定字符串的行,您可以 Loop over the list based on a Condition

  - name: Show lines with TRUE only
    debug:
      msg: "{{ item }}"
    when: "'TRUE' in item"
    loop: "{{ RESULT.STDOUT_LINES }}"

导致输出

TASK [Show lines with TRUE only] *******************************
ok: [localhost] => (item=zimbraIsDelegatedAdminAccount: TRUE) =>
  msg: 'zimbraIsDelegatedAdminAccount: TRUE'

进一步的文档


如果你想包含之前的行,你可以使用像

这样的方法
  - name: Show lines with TRUE and line before
    debug:
      msg: "{{ RESULT.STDOUT_LINES[ansible_loop.index0 - 1] }}\n{{ item }}"
    when: "'TRUE' in item"
    loop: "{{ RESULT.STDOUT_LINES }}"
    loop_control:
      extended: true
      label: "{{ ansible_loop.index0 }}"

导致输出

TASK [Show lines with TRUE and line before] *************************************************************************************************************************************
ok: [localhost] => (item=6) =>
  msg: |-
    # name prueba7@prueba7.com
    zimbraIsDelegatedAdminAccount: TRUE

更多文档


由于您使用的是 shell 模块,因此您也可以使用类似

的方法
- name: DELEGATED ADMIN ACCOUNTS - check, get and send to the file domain.list
  shell: 
    cmd: /opt/zimbra/bin/zmprov -l gaaa -v zimbraIsDelegatedAdminAccount | grep -B 1 TRUE

并仅收集前一行 true 的结果行。

进一步问答

  • grep a file, but show several surrounding lines?

关于

... send it to the file.txt

你可以看看

  • Ansible - Save registered variable to file
  • ...

创建字典

    - set_fact:
        info: "{{ info|d({})|combine({_key: _val}) }}"
      loop: "{{ stdout.split('#')[1:] }}"
      vars:
        _list: "{{ item.split('\n')|map('trim') }}"
        _key: "{{ _list.0.split(' ')|last }}"
        _val: "{{ _list[1:]|select()|map('from_yaml')|combine }}"

给予

  info:
    admin@shrrah.esquimail.com:
      zimbraIsDelegatedAdminAccount: false
    prueba5@prueba5.com: {}
    prueba7@prueba7.com:
      zimbraIsDelegatedAdminAccount: true
    prueba9@prueba9.com: {}

那么,模板就很简单了。打印所有项目

    - copy:
        content: |-
          {% for k,v in info.items() %}
          {{ k }}
          {{ v|to_nice_yaml }}
          {% endfor %}
        dest: file.txt

给予

shell> cat file.txt 
admin@shrrah.esquimail.com
zimbraIsDelegatedAdminAccount: false

prueba5@prueba5.com
{}

prueba7@prueba7.com
zimbraIsDelegatedAdminAccount: true

prueba9@prueba9.com
{}

,或明确 select 项

    - copy:
        content: |-
          prueba7@prueba7.com
          {{ info['prueba7@prueba7.com']|to_nice_yaml }}
        dest: file.txt

给予

shell> cat file.txt 
prueba7@prueba7.com
zimbraIsDelegatedAdminAccount: true

备注

其他属性也将被解析,例如

    stdout_lines: [
      "# name admin@shrrah.esquimail.com",
      "zimbraIsDelegatedAdminAccount: FALSE",
      "",
      "# name prueba5@prueba5.com",
      "",
      "# name prueba7@prueba7.com",
      "zimbraIsDelegatedAdminAccount: TRUE",
      "zimbraIsDelegatedRootAccount: TRUE",
      "",
      "# name prueba9@prueba9.com"
    ]

会给

  info:
    admin@shrrah.esquimail.com:
      zimbraIsDelegatedAdminAccount: false
    prueba5@prueba5.com: {}
    prueba7@prueba7.com:
      zimbraIsDelegatedAdminAccount: true
      zimbraIsDelegatedRootAccount: true
    prueba9@prueba9.com: {}

因此

shell> cat file.txt 
prueba7@prueba7.com
zimbraIsDelegatedAdminAccount: true
zimbraIsDelegatedRootAccount: true