我需要用\替换存储在变量中的字符串中的所有/。
我只是想尽可能简单地通过调试对其进行测试,但是无论我如何尝试,我都无法获得仅将字符替换为字符的预期结果。我认为这可能只是单引号/双引号问题,或者\需要以我不知道的某种方式进行转义。
vars:
- SecGroup: '/stuff/foo/thing'
tasks:
- name: Display modified var
debug:
msg: "{{ SecGroup | replace('/','\') }}"
预期输出:\ stuff \ foo \ thing
尝试不同的输出:
- name: Display modified var
debug:
msg: "{{ SecGroup | replace('/','\') }}"
TASK [Display modified var]
ok: [localhost] => {
"msg": "stufffoothing"
}
- name: Display modified var
debug:
msg: "{{ SecGroup | replace('/','\\') }}"
TASK [Display modified var]
fatal: [localhost]: FAILED! => {"msg": "Unexpected failure during module execution."}
- name: Display modified var
debug:
msg: "{{ SecGroup | replace('/','\\\') }}"
TASK [Display modified var]
fatal: [localhost]: FAILED! => {"msg": "Unexpected failure during module execution."}
- name: Display modified var
debug:
msg: "{{ SecGroup | replace('/','\\\\') }}"
TASK [Display modified var]
ok: [localhost] => {
"msg": "\\\\stuff\\\\foo\\\\thing"
}
我还试图还原引号:
- name: Display modified var
debug:
msg: '{{ SecGroup | replace("/","\") }}'
TASK [Display modified var]
fatal: [localhost]: FAILED! => {"msg": "Unexpected failure during module execution."}
我无法解释这个输出
- name: Display modified var
debug:
msg: '{{ SecGroup | replace("/","\\") }}'
TASK [Display modified var]
ok: [localhost] => {
"msg": "\\\\stuff\\\\foo\\\\thing"
}
答案 0 :(得分:0)
我认为您偶然发现了一个涉及YAML转义和Python转义之间相互作用的极端情况。我能够使其正常工作的唯一方法是引入一个保护字符-可以确保\
不是表达式中的最后一个字符,然后我们将其与随后的replace()
一起删除过滤。在这里,我使用分号(;
),但是您可以使用肯定不会出现在SecGroup
字符串中的任何内容。请注意,您选择的报价很重要;用单引号将整个字符串引起来会阻止YAML的转义:
- name: With guard character
debug:
msg: '{{ SecGroup | replace("/","\;") | replace(";", "") }}'
输出:
TASK [With guard character] *******************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "\\stuff\\foo\\thing"
}
这正是您想要的(记住,单个\
在JSON输出中被编码为\\
)。
关于此:
- name: Display modified var
debug:
msg: '{{ SecGroup | replace("/","\\") }}'
TASK [Display modified var]
ok: [localhost] => {
"msg": "\\\\stuff\\\\foo\\\\thing"
}
您成功用两个反斜杠/
替换了\\
。由于必须在JSON输出中将反斜杠编码为\\
,因此最终会以\\\\
表示双反斜杠,因此:
"msg": "\\\\stuff\\\\foo\\\\thing"
意味着您实际上具有字符串:
\\stuff\\foo\\thing
答案 1 :(得分:0)
我想添加一个替代解决方案:
如果您熟悉Python,则可以编写一个自定义过滤器模块,并避免多层转义。例如,如果您要创建具有以下内容的filter_plugins/reslash.py
:
#!/usr/bin/python
def filter_reslash(val):
return val.replace('/', '\\')
class FilterModule(object):
filter_map = {
'reslash': filter_reslash
}
def filters(self):
return self.filter_map
然后您可以像这样编写剧本:
---
- hosts: localhost
gather_facts: false
vars:
- SecGroup: '/stuff/foo/thing'
tasks:
- debug:
msg: "{{ SecGroup | reslash }}"
可以说这是一种更清洁的解决方案。
答案 2 :(得分:0)
@larsks的解决方案对我来说并不完全有效。我需要使用双斜杠\
和后卫字符转义反斜杠,以便使其在Ansible Playbook中正常工作。
这有效:replace('/','\\;') | replace(';', '')
答案 3 :(得分:0)
另一个简单的解决方案是将转义的反斜杠留给ansible本身。这就是我要做的。
- set_fact:
replacer: '\'
- name: With guard character
debug:
msg: '{{ SecGroup | replace("/",replacer)}}'
答案 4 :(得分:0)
如果要在Windows路径上用双反斜杠替换1个反斜杠,则采用相同的解决方法。
- hosts: localhost
gather_facts: False
vars:
- iis_manager_logdir: 'C:\inetpub\logs\manager-logs'
tasks:
- set_fact:
iis_mng_logs: "{{ iis_manager_logdir | regex_replace('\\\\', '\\\\;') | regex_replace(';', '\\\\') }}"
- name: Original path
debug:
msg: "{{ iis_manager_logdir }}"
- name: New path
debug:
msg: "{{ iis_mng_logs }}"