如何删除 null 并替换为 ansible 中的字符串值

How to remove null and replace with a string value in ansible

如何删除 null 并替换为字符串 novlaue

我将以下输出存储在变量 out1

{
    "out1": [
        [
            {
                "destination": "dest-a",
                "interface": "e1/1",
                "metric": "10",
                "name": "A"
            },
            {
                "destination": "dest-b",
                "interface": "e1/2",
                "metric": "10",
                "name": "B"
            },
            {
                "destination": "dest-c",
                "interface": null,
                "metric": "10",
                "name": "C"
            },
            {
                "destination": "dest-d",
                "interface": null,
                "metric": "10",
                "name": "B"
            }
        ]
    ]
}

我的代码中有一个json_query

- debug: msg="{{out1 |json_query(myquery)}}"
  vars:
     myquery: "[].{dest: destination ,int: interface}"        
  register: out2

以上代码将打印以下内容:

{
    "msg": [
        {
            "dest": "dest-a",
            "int": "e1/1"
        },
        {
            "dest": "dest-b",
            "int": "e/12"
        },
        {
            "dest": "dest-c",
            "int": null
        },
        {
            "dest": "dest-d",
            "int": null
        }
    ]
}

我想用字符串 novalue.

替换或删除 null

我查看了一些帖子,发现 default("novalue") 可以解决问题,但在我的情况下它不起作用。我尝试将 default("novalue") 添加到我的 debug 任务中,但出现错误。
我确定错误出在myquery,我interpret/understand default()的方式可能是错误的,可能使用不当。

有人可以帮我吗?

- debug: msg="{{out1 |json_query(myquery)}}"
  vars:
     myquery: "[].{dest: destination ,int: interface|default("novalue")}"        
  register: out2

您正在 jmespath(即 json_query)表达式中使用 jinja2 default 过滤器。这不行。

这种情况下可以使用jmespath函数not_null

剧本:

---
- hosts: localhost
  gather_facts: false

  vars:
    "out1": [
      [
        {
          "destination": "dest-a",
          "interface": "e1/1",
          "metric": "10",
          "name": "A"
        },
        {
          "destination": "dest-b",
          "interface": "e1/2",
          "metric": "10",
          "name": "B"
        },
        {
          "destination": "dest-c",
          "interface": null,
          "metric": "10",
          "name": "C",
        },
        {
          "destination": "dest-d",
          "interface": null,
          "metric": "10",
          "name": "B"
        }
      ]
    ]

  tasks:
    - debug:
        msg: "{{ out1 | json_query(myquery) }}"
      vars:
        myquery: >-
          [].{dest: destination ,int: not_null(interface, 'no value')}

给出:


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

TASK [debug] ******************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "dest": "dest-a",
            "int": "e1/1"
        },
        {
            "dest": "dest-b",
            "int": "e1/2"
        },
        {
            "dest": "dest-c",
            "int": "no value"
        },
        {
            "dest": "dest-d",
            "int": "no value"
        }
    ]
}

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

否则,使用另一个 JMESPath 表达式来实现此目的,您可以使用 or expression ||,它将显示 interface 的值或您可以自由定义的字符串。

因此,鉴于您的 JSON:

[
    {
        "destination": "dest-a",
        "interface": "e1/1",
        "metric": "10",
        "name": "A"
    },
    {
        "destination": "dest-b",
        "interface": "e1/2",
        "metric": "10",
        "name": "B"
    },
    {
        "destination": "dest-c",
        "interface": null,
        "metric": "10",
        "name": "C"
    },
    {
        "destination": "dest-d",
        "interface": null,
        "metric": "10",
        "name": "B"
    }
]

和 JMESPath 查询

[].{dest: destination ,int: interface || 'novalue'}

这会产生

[
  {
    "dest": "dest-a",
    "int": "e1/1"
  },
  {
    "dest": "dest-b",
    "int": "e1/2"
  },
  {
    "dest": "dest-c",
    "int": "novalue"
  },
  {
    "dest": "dest-d",
    "int": "novalue"
  }
]

你的任务最终是:

- debug: 
    msg: "{{ out1 | json_query(_query) }}"
  vars:
     _query: "[].{dest: destination ,int: interface || 'novalue')}"        
  register: out2

问:"如何去掉'null'并用字符串替换'no value'?"

A:变量out1是一个列表列表。让我们迭代它并创建 out2,其中 null 替换为 'no value' 字符串。在每个循环中创建 interface 属性列表,替换 null。将此列表与项目合并并将其添加到新列表中,例如

    - set_fact:
        out2: "{{ out2|d([]) + [item|zip(_item)|map('combine')] }}"
      loop: "{{ out1 }}"
      vars:
        _item: "{{ item|json_query(_query) }}"
        _query: |
          [].{interface: not_null(interface, 'no value')}

给予

  out2:
  - - destination: dest-a
      interface: e1/1
      metric: '10'
      name: A
    - destination: dest-b
      interface: e1/2
      metric: '10'
      name: B
    - destination: dest-c
      interface: no value
      metric: '10'
      name: C
    - destination: dest-d
      interface: no value
      metric: '10'
      name: B