CoderAnswer - 程序员编程问答

用ansible替换字符串中的\

by @Junn Sorran

ansible yaml jinja2

我需要在存储在变量中的字符串中替换所有/ by \。

我只是想尽可能简单地用调试来测试它,但无论我如何尝试它我都没有得到只是将字符替换为字符的预期结果。我认为它可能只是单/双引号问题,或者可能需要以某种我不知道的方式进行转义。

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"
}

1个答案

0 by @larsks

我认为你偶然发现了一个涉及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

相关问题