1

Problem I'm trying to Solve

The problem I am trying to solve is being able to iterate through elements in two bash arrays as well as individual elements such that these elements are not stored previously as variables; they are declared on the spot:

for e in "$(seq -f "number-%g" 0 4) $(seq -f "number-%g" 5 9) number-10" ; do echo $e; done

When I execute this, I see:

$ for e in "$(seq -f "number-%g" 0 4) $(seq -f "number-%g" 5 9) number-10" ; do echo $e; done
number-0 number-1 number-2 number-3 number-4 number-5 number-6 number-7 number-8 number-9 number-10

it seems as is everything is printing out on the same line.

Resources I've consulted

I've read and experimented with resources on these pages:

Experiments I've tried

Experiment 1

This stores the arrays in intermediate variables:

seq1="$(seq -f "number-%g" 0 4)"
seq2="$(seq -f "number-%g" 5 9)"
elem="number-10"
all=("${seq1[@]}" "${seq2[@]}" "${elem}")

Printing this out yields:

$ for e in $all; do echo $e; done
number-0
number-1
number-2
number-3
number-4

which seems to not pick up the second array or the last element.

Experiment 2

Here I explicitly store two arrays instead of generating them with seq, however, I 1.) do not want to store intermediate variables for this question as per "problem I am trying to solve", and 2.) I want to use the seq command as opposed to stating the arrays explicitly.

$ seq1=("number-0" "number-1" "number-2" "number-3" "number-4")
$ seq2=("number-5" "number-6" "number-7" "number-8" "number-9")
$ all=("${seq1[@]}" "${seq2[@]}" "number-10")

Printing this out along with "number-10" yields:

$ for e in "${all[@]}"; do echo $e; done
number-0
number-1
number-2
number-3
number-4
number-5
number-6
number-7
number-8
number-9
number-10

I look forward to hearing some bash tricks! Thanks!

1 Answer 1

2

So, let's talk about this:

$ seq1="$(seq -f "number-%g" 0 4)"
$ seq2="$(seq -f "number-%g" 5 9)"
$ elem="number-10"
$ all=("${seq1[@]}" "${seq2[@]}" "${elem}")
$ declare -p all
declare -a all=([0]=$'number-0\nnumber-1\nnumber-2\nnumber-3\nnumber-4' [1]=$'number-5\nnumber-6\nnumber-7\nnumber-8\nnumber-9' [2]="number-10")
$ for e in $all; do echo $e; done
number-0
number-1
number-2
number-3
number-4

Note declare -p -- that's very handy to inspect the contents of variables.

all is an array variable. When you dereference this as $all, you are effectively doing ${all[0]} -- i.e. only retrieving the first element.

See that the all array only has 3 elements? The seq1 and seq2 variables are not arrays, they are plain "scalar" variables. Similarly to the previous paragraph, you can use array element syntax to refer to scalar variables:

$ x="hello world"
$ declare -p x
declare -- x="hello world"
$ echo "$x"
hello world
$ echo "${x[0]}"
hello world
$ echo "${x[1]}"

$ echo "${x[*]}"
hello world
$ echo "${x[@]}"
hello world

If you want to execute an external command and capture the lines of output, use the mapfile command. You also need to use a process substitution to invoke the external command.

$ unset seq1 seq2 all
$ mapfile -t seq1 < <(seq -f "number-%g" 0 4)
$ mapfile -t seq2 < <(seq -f "number-%g" 5 9)
$ all=("${seq1[@]}" "${seq2[@]}" "${elem}")
$ declare -p all
declare -a all=([0]="number-0" [1]="number-1" [2]="number-2" [3]="number-3" [4]="number-4" [5]="number-5" [6]="number-6" [7]="number-7" [8]="number-8" [9]="number-9" [10]="number-10")
$ printf "%s\n" "${all[@]}"
number-0
number-1
number-2
number-3
number-4
number-5
number-6
number-7
number-8
number-9
number-10

To generate this sequence in bash without using any external tools, use Brace Expansion:

$ all=( "number-"{0..10} )
$ declare -p all
declare -a all=([0]="number-0" [1]="number-1" [2]="number-2" [3]="number-3" [4]="number-4" [5]="number-5" [6]="number-6" [7]="number-7" [8]="number-8" [9]="number-9" [10]="number-10")
1
  • Thanks. Would you recommend I do something other than seq -f ... to generate the number-X values? What is the best dynamic array generator in bash? Jul 23, 2020 at 18:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.