【问题标题】:Ansible Regex ExpressionAnsible 正则表达式
【发布时间】:2020-03-24 11:51:21
【问题描述】:

我正在寻找 Cisco 路由器上具有特定状态的所有端口以将其关闭。我希望通过 std.out 并使用正则表达式来做到这一点,但对正则表达式语法一无所知。

例如,show 命令的输出将类似于以下输出。

 Port       Device          State   Call          DN        Dev State                          
---------- --------------- -------- ------------- ------- ----------- ----
0/1/0      DEV0001         IS       IDLE         2344       ATT
0/1/1      DEV0002         IS       IDLE         2567       ATT
0/1/2      DEV0002         IS       IDLE         2567       DEL

我想做的是将具有 Dev State = ATT 的端口号存储在一个变量中,以便我可以关闭它们。在 Cisco 中,我可以将 show 命令过滤为 - show port |包括 ATT - 这将仅列出包含 Dev State ATT 的端口,但不会在输出中显示任何列标题。从这个输出中,我需要循环并存储端口号。希望这是有道理的。

感谢任何帮助。谢谢。

Ansible 脚本:

 tasks:
   - name: show port
     ios_command:
      commands:
        - show port summary | incl ATT
     register: config
   - set_fact
      myvalue: ""{{ config.stdout | regex_search(??) }}""
      when config.stdout | length > 0 

调试配置输出:

    "stdout_lines": [
        [
            "Total Devices:           4",
            "Total Calls in Progress: 0",
            "Total Call Legs in Use:  0",
            "",
            "Port       Device          Device   Call          Dev     Directory   Dev ",
            "Identifier Name            State    State         Type    Number      Cntl ",
            "---------- --------------- -------- ------------- ------- ----------- ---- ",
            "0/1/0      DEV0001         IS       IDLE          ALG     3880       DEL",
            "0/1/1      DEV0002         IS       IDLE          ALG     3881       ATT",
            "0/1/2      DEV0003         IS       IDLE          ALG                ATT",
            "0/1/3      DEV0004         IS       IDLE          ALG     3882       DEL"
        ]
    ]
} ]

【问题讨论】:

  • 使用 -debug: var=config 的输出更新您的问题
  • 我已经添加了 stdout_lines 输出
  • stdout_lines 是一个列表列表。显然,您需要第一项 stdout_lines.0
  • ok 我在修改行 cols 后仍然收到与以前类似的错误:“{{ config.stdout_lines.0.split() }}”“任务包含一个带有未定义变量的选项。错误是:'list object' 没有属性 'split'\n\n错误似乎出现在
  • config.stdout_lines.0 是一个列表。 split() 一个列表是不可能的。我的答案适用于第一个输出示例。它不适用于您发布的stdout_lines。我不会修复它。无法使用列的名称,因为“设备”正在重复。由于缺少一个“目录”项,因此无法拆分包含数据的行。我希望思科能够为您提供一种可以解析的格式。

标签: regex ansible


【解决方案1】:
  • 应该有config.stdout_linesconfig.stdout
  • 没有必要测试列表。如果列表为空,将跳过循环。
  • 带有数据的行由模式选择'^\d/\d/\d\s*(.*)$'
  • 可以通过更改 when 条件和更改列表来自定义结果 myitems 添加列表 myvalues

下面的任务

    - set_fact:
        myvalues: "{{ myvalues|default([]) + [myitems.4] }}"
      loop: "{{ config.stdout_lines|select('regex', myregex)|list }}"
      vars:
        myregex: '^\d/\d/\d\s*(.*)$'
        myitems: "{{ item.split() }}"
      when: myitems.5 == "ATT"
    - debug:
        var: myvalues

    "myvalues": [
        "2344", 
        "2567"
    ]


通常,可以使用列名创建列表并使用所选数据创建字典。例如
    - set_fact:
        cols: "{{ config.stdout_lines.0.split() }}"
    - set_fact:
        myvalues: "{{ myvalues|default([]) +
                      [dict(cols|zip(myitems))] }}"
      loop: "{{ config.stdout_lines|select('regex', myregex)|list }}"
      vars:
        myregex: '^\d/\d/\d\s*(.*)$'
        myitems: "{{ item.split() }}"
      when: myitems.5 == "ATT"
    - debug:
        var: myvalues

给予

    "myvalues": [
        {
            "Call": "IDLE", 
            "DN": "2344", 
            "Dev": "ATT", 
            "Device": "DEV0001", 
            "Port": "0/1/0", 
            "State": "IS"
        }, 
        {
            "Call": "IDLE", 
            "DN": "2567", 
            "Dev": "ATT", 
            "Device": "DEV0002", 
            "Port": "0/1/1", 
            "State": "IS"
        }
    ]

然后可以选择数据的任意组合。例如

    - set_fact:
        myports: "{{ myvalues|json_query('[].Port') }}"
    - debug:
        var: myports

给出港口列表

    "myports": [
        "0/1/0", 
        "0/1/1"
    ]

【讨论】:

  • 谢谢弗拉基米尔。我需要找到与呼叫状态匹配的端口,而不是 DN。所以输出应该是0/1/0、0/1/1等等。
  • 当然。只需将[myitems.4] 更改为[myitems.0]。端口是列表中的第一项。我添加了一个如何创建任何选择的示例。
  • 是的,我认为是这样,但我在执行脚本时遇到了问题。我收到以下错误 TASK [set_fact] ***************************************** ****************************************************** *********** 致命:[router1]:失败! => {"msg": "意外的模板类型错误发生在 ({{ config.stdout_lines | select('regex', myregex)|list }}): 预期的字符串或缓冲区"} 可能是因为输出的方式在 IOS 中格式化?
  • 下面的帖子说使用 output.stdout | join('') 而不是 stdout_lines 但这给了我 "myvalues": "VARIABLE IS NOT DEFINED!"在调试输出中。 stackoverflow.com/questions/45737295/…
  • 我尝试了您的字典代码,但出现以下错误:TASK [set_fact] ************************** ****************************************************** ****************************************************** ************************************************ 致命:[router1] : 失败的! => {"msg": "该任务包含一个带有未定义变量的选项。错误是:'list object' has no attribute 'lines'\n\n
猜你喜欢
  • 1970-01-01
  • 2016-01-10
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 2018-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多