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이 배열이면 일치하는 배열 요소가 제거됩니다((M)
일치하지 않는 요소를 제거하려면 플래그를 사용하십시오).