Shell Variable – How to Store Output of a for Loop to a Variable

forshellvariable

I have the following shell code:

for value in 10 5 27 33 14  25
do
      echo  $value
done

But what if I want to manipulate the output later? I want to store the entire output in one variable. Is this possible?

Best Answer

It's no different with for loops than with any other commands, you'd use command substitution:

variable=$(
  for value in 10 5 27 33 14  25
  do
    echo "$value"
  done
)

Would store the whole output minus the last newline character added by the last echo as a string into the scalar $variable variable.

You'd then do for instance:

printf '%s\n' "$variable" | further-processing

Or:

futher-processing << EOF
$variable
EOF

In the bash shell, you can also store each line of the output into an element of an array with:

readarray -t array < <(
  for value in 10 5 27 33 14  25
  do
    echo "$value"
  done
)

To store each space/tab/newline delimited word (assuming the default value of $IFS) of the output into an array, you can use the split+glob operator with the glob part disabled

set -o noglob # not needed in zsh which does only split upon unquoted
              # command substitution. zsh also splits on NULs by default
              # whilst other shells either removes them or choke on them.
array=(
  $(
    for value in 10 5 27 33 14  25
    do
      echo "$value"
    done
  )
)

With zsh/bash/ksh93, you can also do things like:

array=()
for value in 10 5 27 33 14 25
do
  array+=( "$(cmd "$value")" )
done

To build the array.

Then in all those, you'd do:

further-processing "${array[@]}"

To pass all the elements of the array as arguments to futher-processing or:

printf '%s\n' "${array[@]}" | further-processing

To print each element on one line, piped to further-processing

Beware however that if the array is empty, that still prints an empty line. You can avoid that by using print -rC1 -- instead of printf '%s\n' in zsh or in any Bourne-like shell, define a function such as:

println() {
  [ "$#" -eq 0 ] || printf '%s\n' "$@"
}
Related Question