Loop through an array of strings in Bash?

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 

22 Answers

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" ) 
9

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.

11

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

Yes

for Item in Item1 Item2 Item3 Item4 ; do echo $Item done 

Output:

Item1 Item2 Item3 Item4 

To preserve spaces; single or double quote list entries and double quote list expansions.

for Item in 'Item 1' 'Item 2' 'Item 3' 'Item 4' ; do echo "$Item" done 

Output:

Item 1 Item 2 Item 3 Item 4 

To make list over multiple lines

for Item in Item1 \ Item2 \ Item3 \ Item4 do echo $Item done 

Output:

Item1 Item2 Item3 Item4 

Simple list variable
List=( Item1 Item2 Item3 ) 

or

List=( Item1 Item2 Item3 ) 

Display the list variable:

echo ${List[*]} 

Output:

Item1 Item2 Item3 

Loop through the list:

for Item in ${List[*]} do echo $Item done 

Output:

Item1 Item2 Item3 

Create a function to go through a list:

Loop(){ for item in ${*} ; do echo ${item} done } Loop ${List[*]} 

Using the declare keyword (command) to create the list, which is technically called an array:

declare -a List=( "element 1" "element 2" "element 3" ) for entry in "${List[@]}" do echo "$entry" done 

Output:

element 1 element 2 element 3 

Creating an associative array. A dictionary:

declare -A continent continent[Vietnam]=Asia continent[France]=Europe continent[Argentina]=America for item in "${!continent[@]}"; do printf "$item is in ${continent[$item]} \n" done 

Output:

 Argentina is in America Vietnam is in Asia France is in Europe 

CSV variables or files in to a list.
Changing the internal field separator from a space, to what ever you want.
In the example below it is changed to a comma

List="Item 1,Item 2,Item 3" Backup_of_internal_field_separator=$IFS IFS=, for item in $List; do echo $item done IFS=$Backup_of_internal_field_separator 

Output:

Item 1 Item 2 Item 3 

If need to number them:

` 

this is called a back tick. Put the command inside back ticks.

`command` 

It is next to the number one on your keyboard and or above the tab key, on a standard American English language keyboard.

List=() Start_count=0 Step_count=0.1 Stop_count=1 for Item in `seq $Start_count $Step_count $Stop_count` do List+=(Item_$Item) done for Item in ${List[*]} do echo $Item done 

Output is:

Item_0.0 Item_0.1 Item_0.2 Item_0.3 Item_0.4 Item_0.5 Item_0.6 Item_0.7 Item_0.8 Item_0.9 Item_1.0 

Becoming more familiar with bashes behavior:

Create a list in a file

cat <<EOF> List_entries.txt Item1 Item 2 'Item 3' "Item 4" Item 7 : * "Item 6 : * " "Item 6 : *" Item 8 : $PWD 'Item 8 : $PWD' "Item 9 : $PWD" EOF 

Read the list file in to a list and display

List=$(cat List_entries.txt) echo $List echo '$List' echo "$List" echo ${List[*]} echo '${List[*]}' echo "${List[*]}" echo ${List[@]} echo '${List[@]}' echo "${List[@]}" 

BASH commandline reference manual: Special meaning of certain characters or words to the shell.

23

In the same spirit as 4ndrew's answer:

listOfNames="RA RB R C RD" # To allow for other whitespace in the string: # 1. add double quotes around the list variable, or # 2. see the IFS note (under 'Side Notes') for databaseName in "$listOfNames" # <-- Note: Added "" quotes. do echo "$databaseName" # (i.e. do action / processing of $databaseName here...) done # Outputs # RA # RB # R C # RD 

B. No whitespace in the names:

listOfNames="RA RB R C RD" for databaseName in $listOfNames # Note: No quotes do echo "$databaseName" # (i.e. do action / processing of $databaseName here...) done # Outputs # RA # RB # R # C # RD 

Notes

  1. In the second example, using listOfNames="RA RB R C RD" has the same output.

Other ways to bring in data include:

Read from stdin

# line delimited (each databaseName is stored on a line) while read databaseName do echo "$databaseName" # i.e. do action / processing of $databaseName here... done # <<< or_another_input_method_here 
  1. the bash IFS "field separator to line" [1] delimiter can be specified in the script to allow other whitespace (i.e. IFS='\n', or for MacOS IFS='\r')
  2. I like the accepted answer also :) -- I've include these snippets as other helpful ways that also answer the question.
  3. Including #!/bin/bash at the top of the script file indicates the execution environment.
  4. It took me months to figure out how to code this simply :)

Other Sources (while read loop)

4

You can use the syntax of ${arrayName[@]}

#!/bin/bash # declare an array called files, that contains 3 values files=( "/etc/passwd" "/etc/group" "/etc/hosts" ) for i in "${files[@]}" do echo "$i" done 
0

Surprised that nobody's posted this yet -- if you need the indices of the elements while you're looping through the array, you can do this:

arr=(foo bar baz) for i in ${!arr[@]} do echo $i "${arr[i]}" done 

Output:

0 foo 1 bar 2 baz 

I find this a lot more elegant than the "traditional" for-loop style (for (( i=0; i<${#arr[@]}; i++ ))).

(${!arr[@]} and $i don't need to be quoted because they're just numbers; some would suggest quoting them anyway, but that's just personal preference.)

1

This is also easy to read:

FilePath=( "/tmp/path1/" #FilePath[0] "/tmp/path2/" #FilePath[1] ) #Loop for Path in "${FilePath[@]}" do echo "$Path" done 
1

Simple way :

arr=("sharlock" "bomkesh" "feluda" ) ##declare array len=${#arr[*]} # it returns the array length #iterate with while loop i=0 while [ $i -lt $len ] do echo ${arr[$i]} i=$((i+1)) done #iterate with for loop for i in $arr do echo $i done #iterate with splice echo ${arr[@]:0:3} 

I used this approach for my GitHub updates, and I found it simple.

## declare an array variable arr_variable=("kofi" "kwame" "Ama") ## now loop through the above array for i in "${arr_variable[@]}" do echo "$i" done 

You can iterate through bash array values using a counter with three-expression (C style) to read all values and indexes for loops syntax:

declare -a kofi=("kofi" "kwame" "Ama") # get the length of the array length=${#kofi[@]} for (( j=0; j<${length}; j++ )); do print (f "Current index %d with value %s\n" $j "${kofi[$j]}") done 
1
listOfNames="db_one db_two db_three" for databaseName in $listOfNames do echo $databaseName done 

or just

for databaseName in db_one db_two db_three do echo $databaseName done 
0

Implicit array for script or functions:

In addition to anubhava's correct answer: If basic syntax for loop is:

for var in "${arr[@]}" ;do ...$var... ;done 

there is a special case in :

When running a script or a function, arguments passed at command lines will be assigned to $@ array variable, you can access by $1, $2, $3, and so on.

This can be populated (for test) by

set -- arg1 arg2 arg3 ... 

A loop over this array could be written simply:

for item ;do echo "This is item: $item." done 

Note that the reserved work in is not present and no array name too!

Sample:

set -- arg1 arg2 arg3 ... for item ;do echo "This is item: $item." done This is item: arg1. This is item: arg2. This is item: arg3. This is item: .... 

Note that this is same than

for item in "$@";do echo "This is item: $item." done 

Then into a script:

#!/bin/bash for item ;do printf "Doing something with '%s'.\n" "$item" done 

Save this in a script myscript.sh, chmod +x myscript.sh, then

./myscript.sh arg1 arg2 arg3 ... Doing something with 'arg1'. Doing something with 'arg2'. Doing something with 'arg3'. Doing something with '...'. 

Same in a function:

myfunc() { for item;do cat <<<"Working about '$item'."; done ; } 

Then

myfunc item1 tiem2 time3 Working about 'item1'. Working about 'tiem2'. Working about 'time3'. 

The declare array doesn't work for Korn shell. Use the below example for the Korn shell:

promote_sla_chk_lst="cdi xlob" set -A promote_arry $promote_sla_chk_lst for i in ${promote_arry[*]}; do echo $i done 
3

Try this. It is working and tested.

for k in "${array[@]}" do echo $k done # For accessing with the echo command: echo ${array[0]}, ${array[1]} 
2

This is similar to user2533809's answer, but each file will be executed as a separate command.

#!/bin/bash names="RA RB R C RD" while read -r line; do echo line: "$line" done <<< "$names" 

If you are using Korn shell, there is "set -A databaseName ", else there is "declare -a databaseName"

To write a script working on all shells,

 set -A databaseName=("db1" "db2" ....) || declare -a databaseName=("db1" "db2" ....) # now loop for dbname in "${arr[@]}" do echo "$dbname" # or whatever done 

It should be work on all shells.

1

What I really needed for this was something like this:

for i in $(the_array); do something; done 

For instance:

for i in $(ps -aux | grep vlc | awk '{ print $2 }'); do kill -9 $i; done 

(Would kill all processes with vlc in their name)

How you loop through an array, depends on the presence of new line characters. With new line characters separating the array elements, the array can be referred to as "$array", otherwise it should be referred to as "${array[@]}". The following script will make it clear:

#!/bin/bash mkdir temp mkdir temp/aaa mkdir temp/bbb mkdir temp/ccc array=$(ls temp) array1=(aaa bbb ccc) array2=$(echo -e "aaa\nbbb\nccc") echo '$array' echo "$array" echo for dirname in "$array"; do echo "$dirname" done echo for dirname in "${array[@]}"; do echo "$dirname" done echo echo '$array1' echo "$array1" echo for dirname in "$array1"; do echo "$dirname" done echo for dirname in "${array1[@]}"; do echo "$dirname" done echo echo '$array2' echo "$array2" echo for dirname in "$array2"; do echo "$dirname" done echo for dirname in "${array2[@]}"; do echo "$dirname" done rmdir temp/aaa rmdir temp/bbb rmdir temp/ccc rmdir temp 

Possible first line of every Bash script/session:

say() { for line in "${@}" ; do printf "%s\n" "${line}" ; done ; } 

Use e.g.:

$ aa=( 7 -4 -e ) ; say "${aa[@]}" 7 -4 -e 

May consider: echo interprets -e as option here

Single line looping,

 declare -a listOfNames=('db_a' 'db_b' 'db_c') for databaseName in ${listOfNames[@]}; do echo $databaseName; done; 

you will get an output like this,

db_a db_b db_c 

Declare an array of string with type

declare -a StringArray=("Linux Mint" "Fedora" "Red Hat Linux" "Ubuntu" "Debian" ) 

Iterate the string array using for loop

for val in ${StringArray[@]}; do echo $val done 

Output

enter image description here

I loop through an array of my projects for a git pull update:

#!/bin/sh projects=" web ios android " for project in $projects do cd $HOME/develop/$project && git pull end 
2

You Might Also Like