O principal problema aqui é que a segunda linha, IFS=, sentences1=($sentences)
, define o IFS como "," permanentemente; Isso significa que você obtém um comportamento de análise estranho e inesperado em todo o restante do script. Observe que, com algo como IFS=, read ...
, isso não aconteceria porque a atribuição do IFS é tratada como aplicável somente ao comando read
; mas em IFS=, sentences1=($sentences)
, não há comando real, apenas atribuições, então as atribuições são tratadas como aplicáveis a todo o shell.
Então, vamos dar uma olhada no que acontece no restante do script. sentences2=$sentences
apenas copia sentences
para sentences2
, então for sentence in ${sentences2[@]}
é um pouco estranho. sentences2
não é uma matriz (apenas uma string simples), portanto, o [@]
bit não faz nada, mas como o IFS ainda é ",", ele é "dividido em palavras" em "Hello World" e " Perguntas "- ou seja, você obtém o resultado certo, mas pelo motivo errado.
(Nota: se fosse um array real, você gostaria de ter aspas duplas em torno dele, como em for sentence in "${sentences2[@]}"
para evitar que os elementos sejam divididos em palavras.)
O próximo comando, for i in $(seq 1 2)
, é onde o problema real começa. seq 1 2
imprime "1 [newline] 2 [newline]", a construção $( )
recorta a nova linha à direita e, em seguida, "1 [newline] 2" gera divisão de palavras, mas como não há vírgula, ela é tratada como uma palavra (que contém uma nova linha). Assim, o loop interno é executado apenas uma vez, com i
definido como "1 [newline] 2".
A próxima linha, echo $i $sentence
, imprime "1 [newline] 2" seguida por um espaço, seguido pelo conteúdo de sentence
. Na primeira iteração, com sentence
definido como "Hello World", isso imprime:
1
2 Hello World
... a nova linha no meio faz parecer duas coisas sendo impressas, mas na verdade é apenas uma echo
que contém uma nova linha.
Portanto, duas grandes recomendações: Primeiro, quando você alterar o IFS, altere-o novamente depois. Segundo, sempre duplique as referências de variáveis para evitar a divisão inesperada de palavras (e a expansão de curingas). Aqui está o que recebo para o script:
#!/bin/bash
sentences="Hello World,Questions"
saveIFS="$IFS"
IFS=, sentences1=($sentences)
IFS="$saveIFS" # Set IFS back to normal!
for sentence in "${sentences1[@]}"; do # Note double-quotes, and sentences1 is
an actual array
for i in $(seq 1 2); do # No double-quotes, we *want* seq's output to be spli
t
echo "$i" "$sentence" # Double-quotes for safety
done
done