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

3

NB: Li as respostas para outras perguntas semelhantes ( Como dividir a saída e armazená-lo em uma matriz? , Como dividir uma string em uma matriz no bash ), mas nenhum deles responde à pergunta específica que estou fazendo aqui.

Suponha que a saída de algum comando foo seja 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 saída de foo nas guias sem precisar de uma atribuição intermediária para tmpvar ?

FWIW, isso não funciona:

fields=( ${(ps:\t:)$( foo )} )
echo $#fields
# 1
    
por kjo 18.04.2017 / 13:53

3 respostas

3
$ 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, o s:\t: aplica-se à união (com o primeiro caractere de $IFS ) dos campos resultantes do $IFS -split da substituição do comando.

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

$ (IFS=; printf '<%s>\n' ${(ps:\t:)$(printf 'foo bar\t\tbaz')})
<foo bar>
<baz>
    
por 18.04.2017 / 14:12
3

Você deve citar o $ (foo)

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

Você pode encontrar aqui alguns exemplos interessantes

    
por 18.04.2017 / 14:13
0
IFS=" "; set -f
a=( $(echo -e "a b\tc d") )
printf '<%s>\n' "size=${#a[@]}" "${a[@]}"
    
por 18.04.2017 / 14:42

Tags