52

Is there any way to pipe the output of a command which lists a bunch of numbers (each number in a separate line) and initialize a bash array with those numbers?

Details: This lists 3 changelist numbers which have been submitted in the following date range. The output is then piped to cut to filter it further to get just the changelist numbers.

p4 changes -m 3 -u edk -s submitted @2009/05/01,@now | cut -d ' ' -f 2

E.g. :

422311
543210
444000

How is it possible to store this list in a bash array?

0

3 Answers 3

73

You can execute the command under ticks and set the Array like,

ARRAY=(`command`)

Alternatively, you can save the output of the command to a file and cat it similarly,

command > file.txt
ARRAY=(`cat file.txt`)

Or, simply one of the following forms suggested in the comments below,

ARRAY=(`< file.txt`)
ARRAY=($(<file.txt))
Sign up to request clarification or add additional context in comments.

7 Comments

Useless use of cat: <file.txt does the same.
fixed the answer for future reference.
Whenever possible, avoid the use of back quotes. This is more readable and can work with nesting without awkward quoting: ARRAY=($(command)) or ARRAY=($(< file.txt))
Be warned that this will ALWAYS use whitespace to separate elements. stackoverflow.com/questions/9449417/… reports possibility to handle whitespace by setting IFS to '\n' but I couldn't make it accept '\0'.
Why does folders=(`ls -1 ${FOLDER} | xargs`) give me Syntax error: "(" unexpected ?
|
16

If you use bash 4+, it has special command for this: mapfile also known as readarray, so you can fill your array like this:

declare -a a
readarray -t a < <(command)

for more portable version you can use

declare -a a
while read i; do
  a=( "${a[@]}" "$i" )
done < <(command)

6 Comments

This is my first time seeing < <(command). Can you please help me find more detail on this syntax. I'm interested in knowing why it needs 2 < to work. Thanks
First < is redirection of input stream, see gnu.org/software/bash/manual/html_node/… for detains. Construction <(command) means that output of command is piped to named fifo (usually /dev/fdn), you can find details on it at gnu.org/software/bash/manual/html_node/….
Be warned that readarray doesn't support an alternative separator, it always uses newline.
a[${#a[*]}]=value or a+=(value) is a better syntax to append to an array.
Re @ivan_pozdeev readarray/mapfile apparently does support defining alternative delimiters. The docs specify -d delim: "The first character of delim is used to terminate each input line, rather than newline."
|
3

Quite similar to #4 but looks a bit better for me. :)

declare -a a
readarray -t a <<< $(command)

1 Comment

Interesting alternative. However the methods differ in case of an empty output from the command, the here-string method gives an array having one empty item, whereas the names pipe method gives an empty array.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.