如果輸入是變數而不是內聯,zsh 參數擴展替換模式會以不同的方式解析字串

如果輸入是變數而不是內聯,zsh 參數擴展替換模式會以不同的方式解析字串

如果輸入是變數而不是內聯變量,則 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 周圍有一個多餘的多餘部分,已在上面刪除)


在預設zshshell 中,參數擴充不需要引用來避免分裂IFS(但這也不會造成傷害)。不加引號命令替換會被 分割IFS,因此必須引用以避免這種情況。

手冊zshexpn(1)

PARAMETER EXPANSION

SH_WORD_SPLIT特別要注意的是,除非設定了該選項,否則未加引號的參數的單字不會自動在空格上分割;有關更多詳細信息,請參閱下面對此選項的引用。這是與其他 shell 的一個重要區別。然而,與其他 shell 一樣,未加引號的參數擴充中會忽略空字。

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)標誌刪除不符合的元素)。

相關內容