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
작동하지 않습니다. 왜냐하면 문자열 연산이 변수의 내용에 적용되는 경우도 있기 때문입니다.
답변1
${(q)…}
그 변형은 '…'
, "…"
또는 $'…'
따옴표를 사용하지만 print -P
따옴표 확장은 수행하지 않고 백슬래시 확장 및 힌트 확장만 수행합니다(퍼센트 이스케이프 확장 및 prompt_subst
활성화된 경우 대체 포함). 그래서 ${(q)…}
여기서는 도움이 되지 않는다고 생각합니다.
비활성화되면 prompt_subst
백슬래시와 백분율 기호를 보호해야 합니다. 활성화되면 prompt_subst
달러와 백틱도 보호해야 합니다.
if [[ -o prompt_subst ]]; then
print -P -- "${${${${my_var//\\/\\\\\\\\}//\%/%%}//\$/\\\\\$}//\`/\\\\\`}"
else
print -P -- "${${my_var//\\/\\\\}//\%/%%}"
fi
답변2
목적이 일부 문자열을 인쇄하는 것인데, 그 중 일부는 빠르게 확장되어야 하거나 \x
일부는 확장되어서는 안 되는 경우 다음을 수행하는 대신:
print -P -- $string_to_undergo_both \
${string_to_undergo_prompt//\\/\\\\} \
${string_to_undergo_backslash//complex-brittle-expression} \
${string_to_undergo_none//complex-brittle-expression} \
다음과 같이 나눌 수 있습니다.
print -P -n -- $string_to_undergo_both' '
print -rP -n -- $string_to_undergo_prompt' '
print -n -- $string_to_undergo_backslash' '
print -r -- $string_to_undergo_none
( 이 옵션이 활성화된 print -rP
경우 with는 자신 뿐만 아니라 이스케이프에도 사용된다는 점에서 여전히 특별하므로 대신 출력됩니다 .)promptsubst
\
$
`
print -rP '\\'
\
\\
또는 print -r --
이를 호출하여 aw를 인쇄하지만 ( r
Korn 쉘과의 호환성을 위해 \x
기본적으로 켜져 있는 확장을 비활성화 print
), 필요한 경우 매개변수 확장 플래그를 사용하여 프롬프트 확장 또는 백슬래시 확장을 활성화합니다.
print -r -- ${(g[o]%)string_to_undergo_both} \
${(%)string_to_undergo_prompt} \
${(g[o])string_to_undergo_backslash} \
$string_to_undergo_none
${(flags):-literal-text}
${(%):-%F{red}}
따옴표( 예: 프롬프트 확장) 를 사용하거나 $'...'
백슬래시 확장을 위해 리터럴 텍스트(변수가 아닌)에 대해 이를 활성화할 수도 있습니다.
%%
전체 프롬프트 확장(활성화된 경우 위험한 응용 프로그램 포함 promptsubst
)과 e
매개변수 확장, 명령 대체 및 산술 확장을 수행하려면 매개변수 확장 플래그 도 참조하세요 .
의 경우 printf
백슬래시 확장은 형식 매개변수와 형식 지시문에 대한 인수 모두에서 수행됩니다 (그러나 일반 C 스타일이 아닌 %b
후자 스타일에서 ). echo
그러나 신속한 확장을 위한 형식 지시문은 없습니다.
그러나 힌트 확장을 사용하면 배열을 통해 축어적 텍스트를 전달할 수도 있습니다(단, 제어 문자와 같이 인쇄할 수 없는 문자는 일부 시각적 표현(예: \n
개행, ^[
ESC, U+FFFE)으로 변환된다는 점에 유의하세요.\ufffe
$psvar
$ psvar=( '\\' %% )
$ print -P 'first is %F{red}%1v%f, second is %F{green}%2v%f'
first is \\, second is %%
따라서 다음 명령을 사용하여 프롬프트 확장을 활성화할 수 있습니다 printf
.
pprintf() {
local psvar=("${(@)argv[2,-1]}")
print -P -- "$1"
}
$ pprintf 'cwd: %~, host: %m, arbitrary printable string: "%1v"' '\\%%'
cwd: ~, host: myhost, arbitrary printable string: "\\%%"
(백슬래시 확장도 여기서 수행됩니다. -r
비활성화하려면 추가하세요).