如何用Ansible正则解析含多行变量的.env文件
请注意:解决此问题总有其他方案,但这更像是一个趣味/挑战——请聚焦问题本身,即如何用有效正则在Ansible中解析.env文件。我已经接近目标了。
我有一个.env文件,想要在Ansible剧本中将其解析为Ansible变量。目前已实现解析简单的key=value对,同时忽略注释和空行。
当前使用的正则替换语句为:
map('regex_replace', '([^=]*)=(.*)', '\1: \2')
它可以解析如下格式的.env内容:
KEY2=SOME_TEXT KEY3="SOME_MORE_TEXT" KEY4='EVEN_MORE_TEXT'
问题
但当文件中包含多行变量时(如KEY1),正则会把变量值内部的=也替换成:,破坏原有内容:
KEY1='{ "string" = { "key" = "value", "key" = "value" } }'
当前剧本关键代码:
set_fact: env_vars: "{{ (env_file_content.content | b64decode).split('\n') | map('regex_replace', '^#.*', '') | select | map('regex_replace', '([^=]*)=(.*)', '\1: \2') | join('\n') | from_yaml }}"
完整.env文件内容:
# IN TOTAL, THE REGEX SHOULD MATCH 4 KEY-VALUE PAIRS FROM THIS FILE. KEY1='{ "string" = { "key" = "value", "key" = "value" }, "string" = { "key" = "value", "key" = "value" } }' # DO NOT MATCH ON COMMENTS, EVEN THOSE WITH X=Y in them. # ALSO IGNORE THIS COMMENT, AND NEW LINES AROUND. KEY2=SOME_TEXT KEY3="SOME_MORE_TEXT" KEY4='EVEN_MORE_TEXT'
需求
- 正则需生成4个可通过
env_vars.PREFIX_KEY1这类方式访问的变量; - 正则需不修改KEY1内部的任何内容,保持原样;
- 为每个变量添加
PREFIX_前缀,且前缀仅添加到变量名上,不会影响变量值内部内容。
解决方案
1. 修改正则匹配规则
使用支持多行匹配的正则,区分两种变量格式,避免误匹配变量值内部的=:
- 单引号包裹的多行变量:直接捕获从开头单引号到闭合单引号的所有内容(含换行)
- 普通单行变量:捕获
=到行尾/注释前的内容
替换正则表达式:
'^(\w+)=''(?s)(.*?)''|^(\w+)=([^#\n]+)'
替换模板:
'PREFIX_\\1\\3: \\2\\4'
正则说明:
^(\w+): 匹配行首的变量名(仅字母、数字、下划线)=''(?s)(.*?)'': 匹配单引号包裹内容,(?s)开启DOTALL模式让.匹配换行,.*?非贪婪匹配到闭合单引号|: 分支匹配,处理普通单行变量^(\w+)=([^#\n]+): 匹配单行变量,捕获=后到行尾或注释前的内容
2. 调整Ansible处理流程
不再按行拆分内容,直接对整个文件内容处理,避免破坏多行变量结构:
set_fact: env_vars: | {{ (env_file_content.content | b64decode) # 移除所有注释行 | regex_replace('^#.*$', '', multiline=True) # 移除空行 | regex_replace('^\s*$', '', multiline=True) # 全局替换为带前缀的YAML格式 | regex_replace('^(\w+)=''(?s)(.*?)''|^(\w+)=([^#\n]+)', 'PREFIX_\\1\\3: \\2\\4', multiline=True) | from_yaml }}
3. 验证效果
处理后env_vars将包含4个符合要求的变量:
env_vars.PREFIX_KEY1: 保留原始单引号内的结构,内部=未被修改env_vars.PREFIX_KEY2: 值为SOME_TEXTenv_vars.PREFIX_KEY3: 值为"SOME_MORE_TEXT"env_vars.PREFIX_KEY4: 值为'EVEN_MORE_TEXT'
可通过debug模块验证:
debug: var: env_vars.PREFIX_KEY1
内容的提问来源于stack exchange,提问作者Jimbo
相关产品推荐
相关产品推荐

