Como dividir a saída do comando e atribuir o resultado a um array usando apenas uma única expressão?

Como dividir a saída do comando e atribuir o resultado a um array usando apenas uma única expressão?

Observação:Eu li as respostas para outras perguntas semelhantes (Como dividir a saída e armazená-la em um array?,Como dividir uma string em um array no bash), mas nenhum deles responde à pergunta específica que estou fazendo aqui.


Suponha que a saída de algum comando fooseja uma única linha composta por 10 campos separados por tabulações. Então

tmpvar=$( foo )
fields=( ${(ps:\t:)tmpvar} )
echo $#fields
# 10

P:Como posso obter a mesma divisão da foosaída nas guias sem precisar de uma atribuição intermediária para tmpvar?


FWIW, isso não funciona:

fields=( ${(ps:\t:)$( foo )} )
echo $#fields
# 1

Responder1

$ printf '<%s>\n' "${(@ps:\t:)$(printf 'foo bar\t\tbaz')}"
<foo bar>
<>
<baz>

Ou se você quiser suprimir os elementos vazios como na sua abordagem tempvar:

$ printf '<%s>\n' ${(ps:\t:)"$(printf 'foo bar\t\tbaz')"}
<foo bar>
<baz>

IOW, você precisa citar a substituição do comando. Caso contrário, s:\t:aplica-se à junção (com o primeiro caractere de $IFS) dos campos resultantes da $IFSdivisão da substituição do comando.

Como alternativa, você pode definir $IFSuma string vazia ou um único caractere que não seja um espaço em branco.

$ (IFS=; printf '<%s>\n' ${(ps:\t:)$(printf 'foo bar\t\tbaz')})
<foo bar>
<baz>

Responder2

Você deve citar o $( foo )

fields=( ${(ps:\t:)"$( foo )"} )
echo $#fields

Você pode encontraraqui alguns bons exemplos

Responder3

IFS=" "; set -f
a=( $(echo -e "a b\tc d") )
printf '<%s>\n' "size=${#a[@]}" "${a[@]}"

informação relacionada