Store output of command into the array

This is command: pdc status -a 2>&1 | grep 'okay' It gives the following output

[okay     ]: you are currently listening: 33
[okay     ]: you are currently listening: 22
[okay     ]: you are currently listening: 11

I have written this command in shell scrip file. But I want to store the output of this command into the array for some processing on each of the index value in the array.

How can I store the output of this command into the array?


If you just want the numbers at the end of each line:

numbers=( $(pdc ... | grep -oP 'okay.+?\K\d+$') )

If you want to store each line into the array

mapfile -t lines < <(pdc ...)

To retrieve the data from the arrays:

for (( i=0; i<${#numbers[@]}; i++ )); do echo ${numbers[i]}; done
echo
printf "%s\n" "${lines[@]}"
33
22
11

[okay   ]: you are currently listening: 33
[okay   ]: you are currently listening: 22
[okay   ]: you are currently listening: 11

First of all, you don't necessarily need the array, to process the output line by line you can do:

pdc status -a 2>&1 | grep 'okay' | while read line; do somecommand "$line"; done

If you do need the array, Glenn Jackman already gave you the best way to do it but here's another approach:

#!/bin/bash
IFS=$'\n'
array=($(pdc status -a 2>&1 | grep 'okay'))

Explanation:

  • $IFS=$'\n' : $IFS is bash's input field separator, setting it to the newline character only (\n) ensures that your output lines won't be split on whitespace so that you can save each line as a separate array element. Without this, each word of your command's output would be a different element.

    Depending on what you want to do, it might be a good idea to save the old value of $IFS and restore it after the array is read:

    oldifs="$IFS"
    IFS=$'\n'
    array=($(echo -e "foo bar\nbaz bar"))
    IFS="$oldifs"
    
  • $(command) : This is called command substitution and allows you to save the output of a command in a variable. There are two ways of doing this:

    var=$(command)
    

    and

    var=`command`
    

    Of the two, the $() is better because:

    • It can deal with nested commands:

      var=$(command1 $(command 2))
      

      For example var=$(cat $(find ~/))

    • It has far fewer issues with quoting and results in cleaner syntax. See here for more.


Yet another more intuitive way using readarray builtin (see help -m readarray):

readarray -t array <<< "$(pdc status -a 2>&1 | grep 'okay')"

Next, to print an array element, let say second element, you can use:

echo "${array[1]}"

To print all array elements on separate lines, you can use:

printf -- "%s\n" "${array[@]}"