How could I read user input as an array in the bash shell?
5 Answers
Here's one way to do it:
while read line
do my_array=("${my_array[@]}" $line)
done
echo ${my_array[@]}If you just run it, it will keep reading from standard-input until you hit Ctrl+D (EOF). Afterwards, the lines you entered will be in my_array. Some may find this code confusing. The body of the loop basically says my_array = my_array + element.
Some interesting pieces of documentation:
The Advanced Bash-Scripting Guide has a great chapter on arrays
The manpage of the read builtin
15 array examples from thegeekstuff.com
Read it using this:
read -a arrAnd for printing, use:
for elem in ${arr[@]}
do echo $elem
done And one that doesn't recreate the array each time (though requires bash 3.1 or newer):
array=()
while IFS= read -r -p "Next item (end with an empty line): " line; do [[ $line ]] || break # break if line is empty array+=("$line")
done
printf '%s\n' "Items read:"
printf ' «%s»\n' "${array[@]}"See for more.
And as always, to avoid writing bugs read and avoid the tldp-guides like the Advanced bash scripting guide.
1How about this one-liner ;)
arr=( $(cat -) )
echo ${arr[@]}Edit:
In bash,
arr=(val1 val2 ...)is the way of assigning to an array. Using it in conjunction with command substitution, you can read in arrays from pipeline which is not possible to use read to accomplish this in a straight-forward manner:
echo -e "a\nb" | read -a arr
echo ${arr[@]}You will find that it output nothing due to the fact that read does nothing when stdin is a pipe since a pipeline may be run in a subshell so that the variable may not be usable at all.
Using the way suggested by this answer:
arr=(`echo -e "a\nb"`)
echo ${arr[@]}It gives a b which is way simpler and more straight-forward than any workaround given by the answers of Read values into a shell variable from a pipe and in bash read after a pipe is not setting values.
#!/bin/bash
read line
list=(${line})
for i in ${list[@]};do echo $i
doneOUTPUT
./list-input.sh
banna apple pie
banna
apple
pie