Ansible教程:Jinja2 模板-filter过滤器 作者:马育民 • 2026-09-27 20:27 • 阅读:10001 # 介绍 Filter 是 Jinja2 的 **数据转换工具**,Ansible 同时内置原生 Jinja2 过滤器 + Ansible 扩展过滤器; # 语法 使用管道符 `|`,**所有过滤逻辑运行在控制节点,不是远程主机**;支持链式调用 `var | filter1 | filter2`。 ### 语法格式 ```jinja2 {{ 变量 | 过滤器名(参数) }} {{ var | filter1 | filter2(arg) }} # 链式 ``` 区分:`filter` 用于**转换数据**;`test`(`is`)用于**布尔判断**,不要混淆。 # 变量默认值(高频) **变量未定义/None** 时返回默认值; ``` default("变量",boolean) ``` **参数:** - `boolean=true` 会把空字符串、空列表、0 都当成空。 ### 例子 ``` nano playbook_过滤器.yml ``` 内容如下: ``` --- - name: 测试 Jinja2 filter hosts: localhost gather_facts: false vars: name: 李雷 num: 0 users: - name: Alice enabled: true - name: Bob enabled: false - name: Charlie enabled: true tasks: - name: 判断admin变量是否定义 debug: msg: "{{ admin | default(name) }}" # 没定义admin变量,就使用name变量的值 - name: 判断值为0就取默认值 debug: msg: "{{ num | default(10, boolean=true) }}" # 如果num是0,就取值10 - name: 判断list_var列表类型的变量未定义 debug: msg: "{{ list_var | default([]) }}" # 如果 list_var 未定义就返回 [] ``` **提示:**列表、字典变量一律加 `default([])` / `default({})` 模拟执行: ``` ansible-playbook playbook_过滤器.yml -C -i ansible_client.ini ``` # 空值自定义提示 如果变量没定义,执行时会英文错误,不方便看 使用 `mandatory()`,当变量未定义时,可以给出自定义提示 ```jinja2 {{ app_name | mandatory("必须定义 app_name") }} ``` ### 例子 ``` nano playbook_过滤器_空值自定义提示.yml ``` 内容如下: ``` --- - name: 空值自定义提示 hosts: localhost gather_facts: false tasks: - name: 空值自定义提示 debug: msg: "{{ app_name | mandatory('必须定义 app_name') }}" ``` **提示:**列表、字典变量一律加 `default([])` / `default({})` 模拟执行: ``` ansible-playbook playbook_过滤器_空值自定义提示.yml -C -i ansible_client.ini ``` # 字符串处理过滤器 ### `lower` / `upper`:大小写转换 ```jinja2 {{ "Hello" | lower }} # hello {{ "hello" | upper }} # HELLO ``` ### `regex_replace(pattern, replace, count=0, ignore_case=false)` 正则替换,`count=0` 全部替换 ```jinja2 {{ "a1b2c3" | regex_replace("[0-9]", "") }} # abc ``` ### `split(分隔符)`:字符串切分成列表 ```jinja2 {{ "192.168.1.1" | split(".") }} # ['192','168','1','1'] ``` ### `join(分隔符)`:列表拼接字符串 ```jinja2 {{ ["a","b","c"] | join(",") }} # a,b,c ``` ### `quote`:shell 转义(shell 模块专用,防止注入) ```jinja2 {{ user_input | quote }} ``` ### `b64encode` / `b64decode` base64编解码 ```jinja2 {{ "secret" | b64encode }} {{ "c2VjcmV0" | b64decode }} ``` ### `replace(原串,目标串)`:简单字符串替换 ```jinja2 {{ "test" | replace("es","xx") }} # txx t ``` ### `trim`:去除首尾空白字符 ```jinja2 {{ " abc " | trim }} ``` # 列表/数组过滤器(Ansible 最常用) ### `first` / `last`:取列表第一个/最后一个元素 ```jinja2 {{ [1,2,3] | first }} #1 {{ [1,2,3] | last }} #3 ``` ### `length`:获取长度(字符串、列表、字典都可用) ```jinja2 {{ [1,2,3] | length }} #3 {{ "abc" | length }} #3 ``` ### `unique`:列表去重 ```jinja2 {{ [1,1,2,3] | unique }} # [1,2,3] ``` ### `sort`:列表排序 ```jinja2 {{ [3,1,2] | sort }} # [1,2,3] {{ users | sort(attribute='age') }} # 对象列表按属性排序 ``` ### `map(过滤器)`:对列表每一项执行过滤器 ```jinja2 {{ ["A","B","C"] | map("lower") | list }} # ["a","b","c"] {{ users | map(attribute="name") | list }} #提取所有name字段 ``` ### `select` / `reject`:过滤元素 - `select`:保留满足条件;`reject`:剔除满足条件 ```jinja2 {{ [1,2,3,4] | select("gt",2) | list }} #大于2:3,4 {{ [1,2,3,4] | reject("gt",2) | list }} #<=2:1,2 ``` ### `selectattr` / `rejectattr`:对象列表按属性过滤 ```jinja2 # 保留 status == enabled 的对象 {{ users | selectattr("status","equalto","enabled") | list }} ``` # 字典过滤器 ### `dict2items` / `items2dict`:字典 ↔ 键值对列表转换 ```jinja2 # dict -> [{"key":"k","value":"v"},...] {{ {"name":"tom","age":20} | dict2items }} # 键值列表转回字典 {{ [{"key":"k","value":"v"}] | items2dict }} ``` ### `combine`:合并多个字典(覆盖key) ```jinja2 {{ dict1 | combine(dict2) }} {{ dict1 | combine(dict2, recursive=True) }} #递归合并嵌套字典 ``` # 路径处理过滤器(Ansible扩展) ```jinja2 {{ "/etc/nginx/nginx.conf" | basename }} # nginx.conf {{ "/etc/nginx/nginx.conf" | dirname }} # /etc/nginx {{ "~/.ssh/id_rsa" | expanduser }} #展开家目录 {{ "/a/b/../c" | normpath }} #规范化路径 ``` # 数据序列化:JSON / YAML ```jinja2 {{ data | to_json }} #紧凑json {{ data | to_nice_json }} #带缩进格式化json {{ data | to_yaml }} {{ data | from_json }} #json字符串转对象 {{ data | from_yaml }} ``` # 数学计算 ```jinja2 {{ 10 | int }} #转为整数 {{ 10.5 | float }}#转为浮点数 {{ 3 | pow(2) }} #3^2=9 {{ 5 | round }} #四舍五入 ``` # 时间过滤器 ```jinja2 {{ "%Y-%m-%d" | strftime }} #当前时间格式化 {{ 1727452800 | strftime("%Y-%m-%d") }} #时间戳转日期 ``` 原文出处:/show_1GW47r9VHENV.html