我正在寻找一种方法来转义包含格式说明符和特殊字符(如引号、反斜杠和换行符)的变量,以便在将其传递给print -P
它时会按字面意思打印出来。
所以基本上我希望这两个打印相同:
> cat file.txt
> my_var="$(cat file.txt)"
> print -P "${<magic>my_var}"
我使用的测试用例的一个很好的示例文件是:
Backslash \
Double Backslash \\
Single Quote '
Double Quote "
-----------------------
Escaped Linebreak \n
-----------------------
Color codes: %F{red}not red%f
Variable expansion $SHELL
我得到的最接近的是${${(q+)my_var}//\%/%%}
,尽管引号、换行符、反斜杠和变量扩展存在问题:
$'Backslash Double Backslash \
Single Quote '
Double Quote "
-----------------------
Escaped Linebreak \n
-----------------------
Color codes: %F{red}not red%f
Variable expansion /usr/bin/zsh'
我知道printf '%s\n' "$my_var"
。但是在实践中,print -P
变量周围有很多实际的格式,所以这对我没有用。print -P
遗憾的是,围绕变量和实际变量使用printf
也不起作用,因为在某些情况下,字符串操作被应用于变量的内容。
${(q)…}
及其变体使用'…'
,"…"
或$'…'
引号,但print -P
不进行任何引号扩展,仅进行反斜杠扩展和提示扩展(这是百分比转义扩展,如果prompt_subst
启用,则加上替换)。所以我认为${(q)…}
在这里帮不上忙。禁用时,
prompt_subst
您需要保护反斜杠和百分号。启用后,prompt_subst
您还需要保护美元和反引号。如果目的是打印一些字符串,其中一部分必须进行快速扩展,或者
\x
扩展,其中一部分不进行,而不是这样做:您可以将其分解为:
(请注意
print -rP
,如果promptsubst
启用了该选项,则 with\
仍然是特殊的,因为它用于转义$
,`
和本身,因此print -rP '\\'
将输出\
而不是\\
)。或者调用
print -r --
which printsr
aw (禁用\x
默认打开的扩展print
以与 Korn shell 兼容),但使用参数扩展标志在需要时启用提示扩展或反斜杠扩展:${(flags):-literal-text}
您还可以通过使用(${(%):-%F{red}}
例如用于提示扩展)或$'...'
反斜杠扩展的引号形式启用文字文本(不在变量中) 。另请参阅
%%
参数扩展标志以进行完全提示扩展(包括promptsubst
启用时应用危险),并e
执行参数扩展、命令替换和算术扩展。使用
printf
,在格式参数和%b
格式指令的参数中执行反斜杠扩展(但对于后者的echo
样式,而不是普通的 C 样式)。但是,没有用于快速扩展的格式指令。但是,通过提示扩展,您还可以通过数组传递逐字文本(尽管要注意不可打印的字符,例如控制字符会被转换为一些视觉表示(例如
\n
换行符、^[
ESC、\ufffe
U+FFFE)$psvar
。因此,您可以通过以下方式执行某种启用提示扩展的功能
printf
:(这里也做反斜杠扩展,添加
-r
禁用它)。