Categories
arrays bash shell

Loop through an array of strings in Bash?

2007

I want to write a script that loops through 15 strings (array possibly?) Is that possible?

Something like:

for databaseName in listOfNames
then
  # Do something
end

    3119

    You can use it like this:

    ## declare an array variable
    declare -a arr=("element1" "element2" "element3")
    
    ## now loop through the above array
    for i in "${arr[@]}"
    do
       echo "$i"
       # or do whatever with individual element of the array
    done
    
    # You can access them using echo "${arr[0]}", "${arr[1]}" also
    

    Also works for multi-line array declaration

    declare -a arr=("element1" 
                    "element2" "element3"
                    "element4"
                    )
    

    1

    • 113

      Note that the double quotes around "${arr[@]}" are really important. Without them, the for loop will break up the array by substrings separated by any spaces within the strings instead of by whole string elements within the array. ie: if you had declare -a arr=("element 1" "element 2" "element 3"), then for i in ${arr[@]} would mistakenly iterate 6 times since each string becomes 2 substrings separated by the space in the string, whereas for i in "${arr[@]}" would iterate 3 times, correctly, as desired, maintaining each string as a single unit despite having a space in it.

      Jun 14, 2020 at 20:13


    990

    That is possible, of course.

    for databaseName in a b c d e f; do
      # do something like: echo $databaseName
    done 
    

    See Bash Loops for, while and until for details.

    5

    • 26

      What is the problem with this approach? In simple cases it seems to work and, then, is more intuitive than @anubhava’s answer.

      Aug 30, 2012 at 11:54

    • 20

      This works particularly well with command substitution, eg for year in $(seq 2000 2013).

      – Brad Koch

      May 20, 2013 at 14:53

    • 25

      The ‘declare’ approach works best if you have to iterate over the same array in more than one place. This approach is cleaner but less flexible.

      Jan 3, 2014 at 10:21

    • 20

      Why isn’t this #1? It’s cleaner, and you can easily reuse the array just by setting a string, i.e., DATABASES="a b c d e f".

      Jul 2, 2014 at 21:42

    • 16

      @Nerdmaster: Yes, this is a more simple (and portable) code but storage of the list of strings separated by spaces in a variable (a single string in fact) prevents the individual strings to contain spaces. The reply of user2533809 solves this problem. —— But there is another problem. If the list is very long and has to be updated such update operations require to copy the complete list every time so they will be very slow.

      Nov 24, 2014 at 13:30

    319

    None of those answers include a counter…

    #!/bin/bash
    ## declare an array variable
    declare -a array=("one" "two" "three")
    
    # get length of an array
    arraylength=${#array[@]}
    
    # use for loop to read all values and indexes
    for (( i=0; i<${arraylength}; i++ ));
    do
      echo "index: $i, value: ${array[$i]}"
    done
    

    Output:

    index: 0, value: one
    index: 1, value: two
    index: 2, value: three
    

    8

    • 1

      That’s just for the sake of the example’s output with a counter. It’s also quite trivial to change that, and works just the same.

      – caktux

      Jul 9, 2015 at 5:35

    • 7

      The echo at the end is buggy. You don’t need to quote constants, you need to quote expansions, or can safely just quote both as follows: echo "$i / ${arraylength} : ${array[$i-1]}" — otherwise, if your $i contains a glob it’ll be expanded, if it contains a tab it’ll be changed to a space, etc.

      Jul 9, 2016 at 15:02


    • 1

      @CharlesDuffy $i won’t contain a glob, because it’s the loop counter in this example and so you control its value.

      – bzeaman

      Sep 2, 2016 at 7:01

    • 11

      @bzeaman, sure — but if you’re sloppy about such things then it requires contextual analysis (as you just did) to prove something correct, and re-analysis if that context changes or the code is reused in a different place or for whatever other reason an unexpected control flow is possible. Write it the robust way and it’s correct regardless of context.

      Sep 2, 2016 at 14:57


    • 10

      This won’t work for a sparse array, i.e. if the array is missing elements. For example, if you have array elements A[1]=’xx’, A[4]=’yy’ and A[9]=’zz’, the length will be 3 and the loop won’t process all the elements.

      – Mr Ed

      Dec 12, 2017 at 9:18