Eu tenho uma variável que contém uma seqüência de caracteres delimitada por espaço:
line="1 1.50 string"
Quero dividir essa seqüência de caracteres com espaço como delimitador e armazenar o resultado em uma matriz, para que o seguinte:
echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
saídas
1
1.50
string
Em algum lugar, encontrei uma solução que não funciona:
arr=$(echo ${line})
Se eu executar as instruções de eco acima depois disso, recebo:
1 1.50 string
[empty line]
[empty line]
Eu também tentei
IFS=" "
arr=$(echo ${line})
com o mesmo resultado. Alguém pode ajudar por favor?
set -f; arr=($string); set +f
parece ser mais rápido queread -r -a <<< $string
.Respostas:
Para converter uma string em uma matriz, use
ou
É crucial não usar aspas, pois isso funciona.
fonte
for i in ${arr[@]}; do echo $i; done
echo ${arr[@]}
$line
houver caracteres brilhantes.mkdir x && cd x && touch A B C && line="*" arr=($line); echo ${#arr[@]}
dá 3declare -a "arr=($line)"
irá ignorarIFS
delimitadores dentro de strings entre aspasline='*'
,read -a arr <<<$line
sempre funciona, mas apenasarr=($line)
falha.Tente o seguinte:
fonte
line='*'
In:
arr=( $line )
. A "divisão" vem associada a "glob".Os caracteres universais (
*
,?
e[]
) serão expandidos para nomes de arquivos correspondentes.A solução correta é apenas um pouco mais complexa:
Nenhum problema de globbing; o caractere de divisão é definido
$IFS
, variáveis citadas.fonte
arr=($line)
na resposta aceita sofre de problemas de globbing. Por exemplo, tente:line="twinkling *"; arr=($line); declare -p arr
.<<<
mas pode ser uma boa ideia ainda usar aspas duplas para garantir consistência e legibilidade.Se você precisar de expansão de parâmetro, tente:
Por exemplo, pegue o seguinte código.
Se o diretório atual contendo os arquivos
a.txt
,b.txt
ec.txt
, em seguida, executar o código deve produzir a seguinte saída.fonte
fonte
tr
é supérfluo, mas ele deve varrer"${arr[@]}"
vez, não$arr