Bash Read: Reading comma separated list, last element is missed
With read
, -d
is used to terminate the input lines (i.e. not to separate input lines). Your last "line" contains no terminator, so read
returns false on EOF and the loop exits (even though the final value was read).
echo '0,1,2,3,4,5' | { while read -d, i; do echo "$i"; done; echo "last value=$i"; }
(Even with -d
, read
also uses $IFS
, absorbing whitespace including the trailing \n
on the final value that would appear using other methods such as readarray
)
The Bash FAQ discusses this, and how to handle various similar cases:
- Bash Pitfalls #47 IFS=, read [...]
- BashFAQ 001 How can I read a file [...] line-by-line
- BashFAQ 005 How can I use array variables?
As other answers state, -d
is an end-of-line character, not a field separator. You can do
IFS=, read -a fields <<< "1,2,3,4,5"
for i in "${fields[@]}"; do echo "$i"; done
From man:
-d delim
The first character of delim is used to terminate the input line, rather than newline.
Your element 5 doesn't have a delimiter (comma), so it won't be read.