작은따옴표로 문자열을 인용하는 방법은 무엇입니까?
예를 들어 다음과 같이 할 수 있습니다.
$ printf "%q\n" 'two words'
two\ words
$
단일(또는 이중) 인용 문자열을 출력으로 얻는 방법이 있습니까? 즉:
$ MAGIC 'two words'
'two words'
$
작은따옴표 버전이 읽기 더 쉽다고 생각합니다.
저는 {ba,z}sh에 적합한 답변을 원합니다. POSIX 쉘은 추가 보너스입니다.
답변1
다음과 같이 말하면:
$ value=$'This isn\'t a \n\x1b "correct" test'
$ printf '%s\n' "$value"
This isn't a
"correct" test
POSIXquote () { printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/" ; }
사용:
$ quote "${value}"
'This isn'\''t a
"correct" test'
이 함수는
'
문자열에서 « »(작은따옴표)의 각 인스턴스를 «'\''
»(작은따옴표, 백슬래시, 작은따옴표, 작은따옴표)로 바꾼 다음 문자열의 시작과 끝에 작은따옴표를 추가합니다. 작은따옴표 내에서 특별한 의미를 갖는 유일한 문자는 작은따옴표 문자 자체이므로 이는 완전히 안전합니다. 후행 줄 바꿈은 올바르게 처리되며, 누군가 비슷한 작업을 수행하려는 경우 명령 대체가 후행 줄 바꿈을 깨뜨리는 것을 방지하기 위해 끝에 있는 작은따옴표는 안전한 문자로 두 배가 됩니다.quoted=$(quote "$var")
경고: 위의 ESC(\033 또는 \x1b 또는 십진수 27) 문자는 (기술적으로) 인용되었지만 표시되지는 않습니다. 다른 제어 문자와 마찬가지로 터미널로 전송되면 해를 끼칠 수도 있습니다. $'\033', $'\C-[' 또는 $'\E'로 시각적으로 렌더링될 때만 표시되고 모호하지 않습니다.
세게 때리다printf '%s\n' "${value@Q}" $'This isn\'t a \n\E "correct" test'
다루기 힘든printf '%s\n' ${(q)value} This\ isn\'t\ a\ $'\n'$'\033'\ \"correct\"\ test
다루기 힘든printf '%s\n' ${(qq)value} 'This isn'\''t a "correct" test'
다루기 힘든printf '%s\n' ${(qqq)value} "This isn't a \"correct\" test"
다루기 힘든printf '%s\n' ${(qqqq)value} $'This isn\'t a \n\033 "correct" test'
다루기 힘든printf '%s\n' ${(q-)value} 'This isn'\''t a "correct" test'
다루기 힘든printf '%s\n' ${(q+)value} $'This isn\'t a \n\C-[ "correct" test'
일부 zsh 인용 문자열에 주의하세요. 위의 ESC(\033 또는 \x1b 또는 십진수 27) 문자는 모두 기술적으로 인용되었지만 표시되지는 않습니다. 다른 제어 문자와 마찬가지로 터미널로 전송되면 해를 끼칠 수도 있습니다. $'\033', $'\C-[' 또는 $'\E'로 시각적으로 렌더링될 때만 표시되고 모호하지 않습니다.
~에서배쉬 매뉴얼:
${parameter@operator}
Q
확장은 입력으로 반복적으로 사용할 수 있는 형식으로 매개변수 값을 참조하는 문자열입니다.
~에서zshexpn
매뉴얼 페이지:
q
쉘 특정 문자는 결과 단어에서 백슬래시로 인용됩니다. 인쇄할 수 없거나 유효하지 않은 문자는$'\NNN'
각 옥텟에 대해 별도의 인용문을 사용하여 다음 형식을 사용하여 인용됩니다.이 플래그가 두 번 제공되면 결과 단어가 작은따옴표로 묶이고, 세 번 지정되면 결과 단어가 이러한 형식으로 큰따옴표로 묶이고 인쇄할 수 없거나 유효하지 않은 문자에 대한 특별한 처리가 시도되지 않습니다. 이 플래그가 4번 나타나는 경우 단어는 작은따옴표로 묶이고 앞에 가 붙습니다
$
. 세 가지 형식 모두에서 인용은 쉘이 결과 문자열을 해석하는 방식을 변경하지 않더라도 무조건 수행됩니다.a가 제공 되면
q-
(한 개만 발생할 수 있음q
) 작은 따옴표의 최소 형식이 사용되며 특수 문자를 보호해야 하는 경우에만 문자열을 인용합니다. 일반적으로 이 양식은 가장 읽기 쉬운 출력을 제공합니다.a가 제공 되면
q+
최소한으로 인용된 확장 형식이 사용되며, 이로 인해 인쇄할 수 없는 문자가 를 사용하여 렌더링됩니다$'...'
. 이 참조는 typeset 명령 계열의 값 출력에 사용되는 참조와 유사합니다.
답변2
Zsh에는 적용할 수 있는 많은 인용 옵션이 있습니다.매개변수 확장:
q
쉘 특정 문자는 결과 단어에서 백슬래시로 인용됩니다. 인쇄할 수 없거나 유효하지 않은 문자는
$'\NNN'
각 옥텟에 대해 별도의 인용문을 사용하여 다음 형식을 사용하여 인용됩니다.이 플래그가 두 번 제공되면 결과 단어가 작은따옴표로 묶이고, 세 번 지정되면 결과 단어가 이러한 형식으로 큰따옴표로 묶이고 인쇄할 수 없거나 유효하지 않은 문자에 대한 특별한 처리가 시도되지 않습니다. 이 플래그가 4번 나타나는 경우 단어는 작은따옴표로 묶이고 앞에 가 붙습니다
$
. 세 가지 형식 모두에서 인용은 쉘이 결과 문자열을 해석하는 방식을 변경하지 않더라도 무조건 수행됩니다.a가 주어 지면
q-
(q는 하나만 발생할 수 있음) 작은 따옴표의 최소 형식이 사용되며 특수 문자를 보호해야 하는 경우에만 문자열을 인용합니다. 일반적으로 이 양식은 가장 읽기 쉬운 출력을 제공합니다.a가 제공 되면
q+
최소한으로 인용된 확장 형식이 사용되며, 이로 인해 인쇄할 수 없는 문자가 를 사용하여 렌더링됩니다$'...'
. 이 참조는 typeset 명령 계열의 값 출력에 사용되는 참조와 유사합니다.
그래서 다음과 같은 함수:
MAGIC () {
printf "%s\n" "${(q+)@}"
}
다음과 같은 결과가 출력됩니다:
$ MAGIC 'two words'
'two words'
$ MAGIC 'two words "'
'two words "'
$ MAGIC 'two '"'"'words'
'two '\''words'
답변3
이것은 sed를 사용하는 매우 간단한 솔루션입니다. 입력은 이고 $raw
, 출력은 입니다 $quoted
.
quoted=$(printf '%sz\n' "$raw" | sed "s/'/'\\\\''/g; s/'''/'/g")
quoted="'${quoted%z}'"
비결은 z
후행 개행 문자를 올바르게 처리하는 것입니다. just를 사용하면 printf %s "$raw"
입력이 개행 문자로 끝나지 않을 때 sed의 동작에 의존해야 하며 명령 대체는 항상 후행 개행 문자를 먹게 됩니다.
sed 스크립트의 두 번째 대체는 필요하지 않지만 ''
입력에 연속된 ''가 있는 경우 출력에서 정크를 방지하여 약간 더 나은 출력을 생성합니다.'
이것은 순수한 POSIX sh 솔루션입니다(기본 모드에서도 zsh에서 작동합니다). 또한 쓸모가 없는 것을 방지 ''
하지만 ''
빈 문자열을 유지합니다.
tail=$raw
quoted=
sq=\'
while
case "$tail" in
'') false;;
\'*) quoted="$quoted\\'"; tail="${tail#?}";;
[!\']*\'*) quoted="$quoted'${tail%%$sq*}'\\'"; tail="${tail#*$sq}";;
*) quoted="$quoted'${tail%%$sq*}'"; false;;
esac
do
:
done
if [ -z "$quoted" ]; then quoted="''"; fi