zsh 매개변수 확장 대체 모드는 입력이 인라인 변수가 아닌 변수인 경우 문자열을 다르게 구문 분석합니다.
나는 이것이 캐릭터 이스케이프와 관련이 있다고 생각하지만 그것을 고치는 방법을 모릅니다.
아래 코드에서 , >
& *
는 2.5.8
printf 출력에서 필터링되어야 합니다. 이는 변수의 첫 번째 인수 확장을 사용하여 발생합니다 versions
.
하지만 curl
호출이 인라인인 경우 위의 3개 값은 필터링되지 않습니다.
호출을 인라인으로 만들 curl
면서 3개의 값을 필터링하려면 어떻게 해야 합니까?
#!/usr/bin/env zsh
setopt EXTENDED_GLOB
# variable: 3 values are correctly filtered out
versions=$(curl '--silent' '--location' 'https://api.sdkman.io/2/candidates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8')
printf -- '%s\n' ${${(Z+n+)versions//[*+>][ *+>]# [[:graph:]]##}}
# inlined: 3 values are not filtered out
printf -- '%s\n' ${${(Z+n+)$(curl '--silent' '--location' 'https://api.sdkman.io/2/candidates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8')//[*+>][ *+>]# [[:graph:]]##}}
답변1
견적 $(command)
교체:
printf -- '%s\n' ${(Z+n+)"$(curl '--silent' '--location' 'https://api.sdkman.io/2/candidates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8')"//[*+>][ *+>]# [[:graph:]]##}
${}
(위에서 제거된 expn 주변에 중복 중복이 있습니다)
기본 zsh
쉘 에서는매개변수 확장분열을 피하기 위해 인용은 필요하지 않습니다 IFS
(하지만 그렇다고 해서 나쁠 것도 없습니다). 인용없이명령 대체분할되므로 IFS
이를 방지하려면 인용해야 합니다.
수동 zshexpn(1)
:
PARAMETER EXPANSION
SH_WORD_SPLIT
특히, 이 옵션이 설정되어 있지 않으면 따옴표가 없는 인수에 대한 단어는 자동으로 공백으로 분할되지 않습니다. 자세한 내용은 아래 이 옵션에 대한 참조를 참조하세요. 이는 다른 쉘과의 중요한 차이점입니다. 그러나 다른 쉘과 마찬가지로 따옴표가 없는 매개변수 확장에서는 공백이 무시됩니다.
COMMAND SUBSTITUTION
대체 항목을 큰따옴표로 묶지 않은 경우 인수는 출력을 단어로 나누는 데 사용됩니다
IFS
.
또한 다음과 같이 이러한 문자열을 제거하는 다른 방법이 있을 수도 있습니다.
printf -- '%s\n' ${${=versions}:#([*+>-]|2.5.8)}
따옴표 없이 명령 대체와 함께 사용할 수 있습니다.
printf -- '%s\n' ${$(curl '--silent' '--location' 'https://api.sdkman.io/2/candi'\
'dates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8'):#([*+>-]|2.5.8)}
위의 내용은 형식 매개변수 확장을 사용합니다 ${name:#pattern}
. 설명서에는 다음과 같이 나와 있습니다.
${name:#pattern}
패턴이 name 값과 일치하면 빈 문자열로 바꾸고, 그렇지 않으면 간단히 name 값을 바꿉니다. name이 배열이면 일치하는 배열 요소가 제거됩니다.(M)
일치하지 않는 요소를 제거하려면 이 플래그를 사용하세요.