Bash Read: lecture de la liste séparée par des virgules, le dernier élément est manquant


8

La sortie de la commande ci-dessous est bizarre pour moi. Pourquoi ne me rend-il pas l'élément 5?

$ echo '0,1,2,3,4,5' | while read -d, i; do echo $i; done
0
1
2
3
4

Je m'attendrais à ce que «5» soit également retourné. Courir GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu). L'ajout d'une virgule fonctionne, mais mes données d'entrée n'ont pas de virgule. Suis-je en train de manquer quelque chose?

Réponses:


12

Avec read, -dest utilisé pour terminer les lignes d'entrée (c'est-à-dire pour ne pas séparer les lignes d'entrée). Votre dernière "ligne" ne contient pas de terminateur, donc readretourne false sur EOF et la boucle se termine (même si la valeur finale a été lue).

echo '0,1,2,3,4,5' | { while read -d, i; do echo "$i"; done; echo "last value=$i"; }

(Même avec -d, readutilise également $IFS, absorber les espaces blancs, y compris le suivi \nde la valeur finale qui apparaîtrait en utilisant d'autres méthodes telles que readarray)

La FAQ Bash en discute et explique comment gérer divers cas similaires:


8
J'imagine que l'on pourrait faire read -d, i || [[ -n $i ]]un la Qu'est-ce que cela while read -r line || [[ -n $line ]]signifie?
steeldriver

8

Comme d'autres réponses l'indiquent, -dest un caractère de fin de ligne, pas un séparateur de champ. Tu peux faire

IFS=, read -a fields <<< "1,2,3,4,5"
for i in "${fields[@]}"; do echo "$i"; done

5

De l'homme:

-d délim

Le premier caractère de délimite est utilisé pour terminer la ligne d'entrée, plutôt que la nouvelle ligne.

Votre élément 5 n'a pas de délimiteur (virgule), il ne sera donc pas lu.


Donc, la meilleure solution est de mettre une autre virgule après l'entrée?
Karlo

3
La meilleure solution pourrait être de traiter les données avec autre chose qu'un shell . Étant donné que les répondeurs ici ont répondu à la question actuelle, vous pouvez envisager une question distincte qui démontre votre objectif plus large.
Jeff Schaller

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.