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
-
4
read -r
is quite useful/important sometimes... Stefano's link to the "read builtin manpage" explains its purpose...(to prevent backslash interpretation).– Peter.OMar 9, 2011 at 5:04 -
Read it using this:
read -a arr
And 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 http://mywiki.wooledge.org/BashFAQ/001 for more.
And as always, to avoid writing bugs read http://mywiki.wooledge.org/BashGuide and avoid the tldp-guides like the Advanced bash scripting guide.
-
Nice links... Thanks for pointing out the
IFS
issue. Without nulling it, 'read' sripts all leading and trailing whitespace... and of course the-r
too...– Peter.OMar 9, 2011 at 5:20
How 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.
-
1
-
-
@Melebius I have appended an explanation of it and the advantage of this one-liner. Aug 19, 2019 at 6:45
#!/bin/bash
read line
list=(${line})
for i in ${list[@]};do
echo $i
done
OUTPUT
./list-input.sh
banna apple pie
banna
apple
pie
cat war_and_peace.txt | ./array_test.sh
../array_test.sh < war_and_peace.txt
.