像 Linux EGREP 一样的 REGEX (regex_search) - 使用一个with_items循环使用多模式/范围显示模式匹配行(带空格)

REGEX (regex_search) like Linux EGREP - Show pattern matching lines (with spaces) using multi-pattern/ range using one with_items loop

提问人:AKS 提问时间:10/4/2023 最后编辑:InSyncAKS 更新时间:10/5/2023 访问量:46

问:

Ansible / ansible-playbook 2.9.27

我有以下剧本,我只想显示那些与给定的多“egrep”类似模式匹配的行(来自数据结构(即列表 --> with_items循环)(例如:“pattern1|pattern2|patter3withRange[0-9a-zA-Z]”)。

我怎样才能纯粹在 Ansible 中实现这一点,可能只使用一个 with_items / 循环?

那就太好了:

  • 如果我不必使用 N 不。嵌套循环数(每个模式/字符串) --or--
  • 我不必使用 shell 单行代码 (egrep “string|ab.*yz|giga”)。

这是我的剧本:aks.yml

---
- hosts: localhost
  become: yes
  remote_user: root
  become_user: root
  pre_tasks:
  - name: show pattern matching lines
    #command: 'echo {{ item }} | egrep -i "r[0-9]|goga"'
    ansible.builtin.debug:
      var: "{{ item }}"
    when: ( item | regex_search('r0[0-9]|goga', ignorecase=True))
    with_items:
      - "ar00n_giga"
      - "Schnooka_goga"
      - "lorito_r01_gigaFifa"

运行剧本可以让我:

$ ansible-playbook aks.yml

[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] *************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [localhost]

TASK [show pattern matching lines] *******************************************************************************************************************************************************************************
ok: [localhost] => (item=ar00n_giga) => {
    "ansible_loop_var": "item", 
    "ar00n_giga": "VARIABLE IS NOT DEFINED!", 
    "item": "ar00n_giga"
}

skipping: [localhost] => (item=Schnooka_goga) 

ok: [localhost] => (item=lorito_r01_gigaFifa) => {
    "ansible_loop_var": "item", 
    "item": "lorito_r01_gigaFifa", 
    "lorito_r01_gigaFifa": "VARIABLE IS NOT DEFINED!"
}

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

注意到“范围”和多模式,即在工作范围内使用![0-9]|regex_search(...)

  • 使用 Range 可以成功捕获同时包含 R00 和 R01 的项目字符串,这很棒。r0[0-9]
  • 使用(它也捕获没有模式的第二行。...|gogar0[0-9]

但是,如果我的值在 with_items: 循环中有空格,即如果我添加以下内容,则上述代码不起作用:

with_items:
  - "ar00n_giga"
  - "new goga shooga"
  - "Schnooka_goga"
  - "lorito_r01_gigaFifa"

然后,我收到以下错误消息:

...
TASK [show pattern matching lines] *******************************************************************************************************************************************************************************
ok: [localhost] => (item=ar00n_giga) => {
    "ansible_loop_var": "item", 
    "ar00n_giga": "VARIABLE IS NOT DEFINED!", 
    "item": "ar00n_giga"
}
fatal: [localhost]: FAILED! => {"msg": "template error while templating string: expected token 'end of print statement', got 'goga'. String: {{new goga shooga}}"}

PLAY RECAP *******************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
正则表达式 循环 ansible grep ansible-2.x

评论


答:

1赞 U880D 10/4/2023 #1

在 RHEL 7.9 上使用来自 Red Hat 分发渠道的 Ansible

ansible --version
ansible 2.9.27
...
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, May 30 2023, 03:38:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

最小的示例 playbook

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

  vars:

    ITEMS:
      - "ar00n_giga"
      - "new goga shooga"
      - "Schnooka_goga"
      - "lorito_r01_gigaFifa"

  tasks:

  - name: Show pattern matching lines
    debug:
      msg: "{{ item }}"
    when: ( item | regex_search('r0[0-9]|goga', ignorecase=True))
    loop: "{{ ITEMS }}"

  - name: Show pattern matching lines
    debug:
      var: item
    when: ( item | regex_search('r0[0-9]|goga', ignorecase=True))
    loop: "{{ ITEMS }}"

  - name: Show pattern matching lines
    debug:
      var: item
    when: ( item | regex_search('r0[0-9]|goga', ignorecase=True))
    with_items:
      - "ar00n_giga"
      - "new goga shooga"
      - "Schnooka_goga"
      - "lorito_r01_gigaFifa"

将导致

TASK [Show pattern matching lines] *************
ok: [localhost] => (item=ar00n_giga) =>
  msg: ar00n_giga
ok: [localhost] => (item=new goga shooga) =>
  msg: new goga shooga
ok: [localhost] => (item=Schnooka_goga) =>
  msg: Schnooka_goga
ok: [localhost] => (item=lorito_r01_gigaFifa) =>
  msg: lorito_r01_gigaFifa

TASK [Show pattern matching lines] *************
ok: [localhost] => (item=ar00n_giga) =>
  ansible_loop_var: item
  item: ar00n_giga
ok: [localhost] => (item=new goga shooga) =>
  ansible_loop_var: item
  item: new goga shooga
ok: [localhost] => (item=Schnooka_goga) =>
  ansible_loop_var: item
  item: Schnooka_goga
ok: [localhost] => (item=lorito_r01_gigaFifa) =>
  ansible_loop_var: item
  item: lorito_r01_gigaFifa

TASK [Show pattern matching lines] *************
ok: [localhost] => (item=ar00n_giga) =>
  ansible_loop_var: item
  item: ar00n_giga
ok: [localhost] => (item=new goga shooga) =>
  ansible_loop_var: item
  item: new goga shooga
ok: [localhost] => (item=Schnooka_goga) =>
  ansible_loop_var: item
  item: Schnooka_goga
ok: [localhost] => (item=lorito_r01_gigaFifa) =>
  ansible_loop_var: item
  item: lorito_r01_gigaFifa

从 Python 包索引 (PyPI) 安装 RHEL 7.9 和 Ansible 的结果相同

```bash
ansible --version
...
ansible [core 2.11.12]
...
  python version = 2.7.5 (default, May 30 2023, 03:38:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
  jinja version = 2.11.3
  libyaml = True

简而言之,我无法重现错误(annot.:不断)。


您收到的错误消息

fatal: [localhost]: FAILED! => {"msg": "template error while templating string: expected token 'end of print statement', got 'goga'. String: {{new goga shooga}}"}

是由于任务中的语法不正确导致的,使用debug

var: "{{ item }}"

而不是

var: item

msg: "{{ item }}"

评论

0赞 AKS 10/5/2023
谢谢你的捕捉。同意!每当使用 ansible 模块时,通过循环(with_items / 尤其是 with_nested),它就会变得非常复杂。即不能使用,如果使用 with_items 等,则不能使用 with。{{ var {{ var within }} }}{{
3赞 Vladimir Botka 10/4/2023 #2

循环访问所选列表更容易。例如,给定列表

  data_raw:
    - ar00n_giga
    - new goga shooga
    - Schnooka_goga
    - lorito_r01_gigaFifa
  1. 搜索模式“R0[0-9]|GOGA'
  data_sel: "{{ data_raw|
                select('search', 'r0[0-9]|goga', ignorecase=true) }}"

选择所有项目,因为:

  • 搜索“r0[0-9]”,选择第一个和最后一个项目,然后
  • 搜索“goga”,选择第二项和第三项
  data_sel:
  - ar00n_giga
  - new goga shooga
  - Schnooka_goga
  - lorito_r01_gigaFifa
  1. 更改第二个模式“r0[0-9]|new”
  data_sel: "{{ data_raw|
                select('search', 'r0[0-9]|new', ignorecase=true) }}"

未选择第三项

  data_sel:
  - ar00n_giga
  - new goga shooga
  - lorito_r01_gigaFifa

用于测试的完整 playbook 示例

- hosts: localhost

  vars:

    data_raw:
      - ar00n_giga
      - new goga shooga
      - Schnooka_goga
      - lorito_r01_gigaFifa

    data_sel1: "{{ data_raw|
                   select('search', 'r0[0-9]|goga', ignorecase=true) }}"
    data_sel2: "{{ data_raw|
                   select('search', 'r0[0-9]|new', ignorecase=true) }}"
                
  tasks:

    - debug:
        var: data_sel1
    - debug:
        var: data_sel2

评论

0赞 AKS 10/4/2023
弗拉基米尔 - 太棒了!谢谢。如果data_raw在 group_vars/someFile.yml 中,如果我想从类似的数据对象使用上面的模式,例如:让我们将它们称为 lineinfile' ansible 模块(where 和 'when: ( item | regex_search(' this pattern') ) ),所以我只能添加/插入那些与我在 yml 中定义的正则表达式模式匹配的行。基本上尝试在 /etc/hosts 文件中添加特定于环境的主机条目select()data_set_regex_pattern_to_include: - "r0[0-9]|goga" - "r0[0-9]|gigaF(ifa|ufa)" Will that work if I'm planning to use with_items: "{{ data_set_regex_pattern_to_include }}