使用列表内容创建字典,并使用 Jinja2 对 Ansible 进行计数
Create dictionary with content of a list and it's count with Ansible using Jinja2
我有如下列表:
str_lst:
- "someline user1 OK somedata somecommand"
- "someline user1 OK somedata somecommand"
- "someline user1 OK somedata somecommand"
- "someline user2 OK somedata somecommand"
- "someline user2 OK somedata somecommand"
我必须用 'second field from each line' 创建一个地图:'它很重要'。
我尝试使用以下 Jinja2 代码但不确定如何获取每个项目的总数:
- set_fact:
users: |-
{%- set users = [] -%}
{%- set u_dict = {} -%}
{%- for i in str_lst -%}
{{ users.append(i.split()[1]) }}
{%- endfor -%}
{%- for j in users -%}
{{ u_dict.update({j:j.count(j)}) }}
{%- endfor -%}
{{ u_dict }}
- debug: var=users
输出:
"users": {
"user1": 1,
"user2": 1
}
预期输出:
"users": {
"user1": 3,
"user2": 2
}
任何想法,如何实现这一点?提前致谢
您可以使用名为 listcount 的自定义过滤器,例如:
在您的 playbook 文件夹中创建一个名为 filter_plugins 的文件夹,并创建一个名为 customfilter.py 的文件:
#!/usr/bin/python
class FilterModule(object):
def filters(self):
return {
'listcount': self.listcount
}
def listcount(self, listvar):
result = {}
for l in listvar:
item = l.split()[1]
if item in result:
result[item] += 1
else:
result[item] = 1
return result
剧本:
- hosts: localhost
vars:
str_lst:
- "someline user1 OK somedata somecommand"
- "someline user1 OK somedata somecommand"
- "someline user1 OK somedata somecommand"
- "someline user2 OK somedata somecommand"
- "someline user2 OK somedata somecommand"
tasks:
- set_fact:
users: "{{ str_lst | listcount }}"
- debug:
msg: "{{ users }}"
结果:
ok: [localhost] => {
"msg": {
"user1": 3,
"user2": 2
}
}
没有customfilter,我已经测试了这个jinja2代码,似乎没问题:
tasks:
- set_fact:
users: |-
{%- set dict = {} -%}
{%- for l in str_lst -%}
{%- set i = l.split()[1] -%}
{%- if i in dict -%}
{%- set _ = dict.update({i: dict[i] + 1}) -%}
{%- else -%}
{%- set _ = dict.update({i: 1}) -%}
{%- endif -%}
{%- endfor -%}
{{ dict }}
- debug:
msg: "{{ users }}"
- debug:
msg: "{{ users.user1 }} {{ users.user2 }}"
我有如下列表:
str_lst:
- "someline user1 OK somedata somecommand"
- "someline user1 OK somedata somecommand"
- "someline user1 OK somedata somecommand"
- "someline user2 OK somedata somecommand"
- "someline user2 OK somedata somecommand"
我必须用 'second field from each line' 创建一个地图:'它很重要'。
我尝试使用以下 Jinja2 代码但不确定如何获取每个项目的总数:
- set_fact:
users: |-
{%- set users = [] -%}
{%- set u_dict = {} -%}
{%- for i in str_lst -%}
{{ users.append(i.split()[1]) }}
{%- endfor -%}
{%- for j in users -%}
{{ u_dict.update({j:j.count(j)}) }}
{%- endfor -%}
{{ u_dict }}
- debug: var=users
输出:
"users": {
"user1": 1,
"user2": 1
}
预期输出:
"users": {
"user1": 3,
"user2": 2
}
任何想法,如何实现这一点?提前致谢
您可以使用名为 listcount 的自定义过滤器,例如:
在您的 playbook 文件夹中创建一个名为 filter_plugins 的文件夹,并创建一个名为 customfilter.py 的文件:
#!/usr/bin/python
class FilterModule(object):
def filters(self):
return {
'listcount': self.listcount
}
def listcount(self, listvar):
result = {}
for l in listvar:
item = l.split()[1]
if item in result:
result[item] += 1
else:
result[item] = 1
return result
剧本:
- hosts: localhost
vars:
str_lst:
- "someline user1 OK somedata somecommand"
- "someline user1 OK somedata somecommand"
- "someline user1 OK somedata somecommand"
- "someline user2 OK somedata somecommand"
- "someline user2 OK somedata somecommand"
tasks:
- set_fact:
users: "{{ str_lst | listcount }}"
- debug:
msg: "{{ users }}"
结果:
ok: [localhost] => {
"msg": {
"user1": 3,
"user2": 2
}
}
没有customfilter,我已经测试了这个jinja2代码,似乎没问题:
tasks:
- set_fact:
users: |-
{%- set dict = {} -%}
{%- for l in str_lst -%}
{%- set i = l.split()[1] -%}
{%- if i in dict -%}
{%- set _ = dict.update({i: dict[i] + 1}) -%}
{%- else -%}
{%- set _ = dict.update({i: 1}) -%}
{%- endif -%}
{%- endfor -%}
{{ dict }}
- debug:
msg: "{{ users }}"
- debug:
msg: "{{ users.user1 }} {{ users.user2 }}"