Shell-Script

通過換行符從子shell中拆分zsh數組

  • September 18, 2019

我想從子外殼實例化一個 zsh 數組

myarray=($(somecommand)

我檢查我是否收到了我想要的東西

for element in $myarray ; do echo "===" ; echo $element ; echo "---" ; done

預設情況下,我看到空格(空格和換行符)用於分隔元素。

我還發現我可以使用${(s:-:)"$(somecommand)"}by 來分隔-,在這種情況下空格和換行符不會破壞元素(即數組元素可以包含換行符)。

到目前為止,我只能在換行符處拆分。即如果somecommand返回

Alice
Bob
Arthur C Clarke
Neo
Thomas Anderson

我希望我上面的for循環列印:

===
Alice
---
===
Bob
---
===
Arthur C Clarke
---
===
Neo
---
===
Thomas Anderson
---

我該如何做到這一點?(並且可能指出在手冊中查找的位置。)

本機拆分運算符(除了在不帶引號的命令替換上完成的類似 Bourne 的分$IFS詞之外)帶有s參數擴展標誌:

array=(${(ps:\n:)"$(cmd)"})

將拆分cmd換行符的輸出,丟棄空元素(空行)。

p是啟用這些\x擴展。作為ps:\n:一個常見的別名,它有一個更短的別名:(f用於分割線提要):

array=(${(f)"$(cmd)"})

要保留空行,您可以:

array=("${(f@)$(cmd)"})

現在,請注意,與大多數其他 shell 一樣,命令替換會刪除所有尾隨換行符,因此所有尾隨空行。要保留這些,您可以執行以下操作:

array=("${(f@)$(cmd; echo .)}")
array[-1]=()  # remove that last line added by echo .

$IFS詞:

IFS=$'\n'
array=($(cmd)) # removes empty lines. Note that contrary to other
              # Bourne-like shells, zsh doesn't do globbing there
              # so you don't need the "set -o noglob"

IFS=$'\n\n' # like in ksh93, doubling an IFS-whitespace character
           # removes its special treatment as a whitespace character
array=($(cmd)) # preserves empty lines except the trailing ones

IFS=$'\n\n'
array=($(cmd; echo .)); array[-1]=() # preserves all empty lines.

為避免$IFS全域修改,您可以在匿名函式中執行上述操作:

(){
 local IFS=$'\n\n'
 array=($(cmd; echo .)); array[-1]=()
}

還要注意$array擴展會跳過空元素。因此,如果您想遍歷包括空元素在內的所有元素,則需要:

for i ("$array[@]") ...

或者

for i ("${(@)array}") ...

不是

for i ($array) ...
for i in $array

引用自:https://unix.stackexchange.com/questions/460792