Bash arrays

Here's a translation of Mitch Frazier's " Bash Arrays " from linuxjournal.com.



If you are using the "standard" * NIX shell, you may not be familiar with the useful bash feature of arrays. While arrays in bash are not as cool as they are in P languages ​​(Perl, Python, and PHP) and other programming languages, they are often useful.

Bash arrays only have numeric indices, but they are optional, which means you don't have to explicitly define the values ​​of all the indices. An entire array can be defined by enclosing the entries in parentheses:



  arr=(Hello World)


Individual records can be defined using the familiar syntax (from BASIC (forgive me Dijkstra - translator's note) to Fortran):



  arr[0]=Hello
  arr[1]=World




However, the opposite looks comparatively more ugly. If you need to refer to a specific entry, then:



  echo ${arr[0]} ${arr[1]}


From the man page:



" Curly braces are needed to prevent conflicts when expanding full paths to files. "



In addition, the following weird constructs are available:



  ${arr[*]} #    
  ${!arr[*]}#    
  ${#arr[*]}#    
  ${#arr[0]}#    (  )


$ {! arr [*]} is a relatively new addition to bash and is not part of the original implementation. The following construction shows an example of a simple use of an array. Notice the "[index] = value", this allows you to assign a specific value to a specific record number.



#!/bin/bash

array=(one two three four [5]=five)

echo "Array size: ${#array[*]}"  #   

echo "Array items:" #   
for item in ${array[*]}
do
    printf "   %s\n" $item
done

echo "Array indexes:" #   
for index in ${!array[*]}
do
    printf "   %d\n" $index
done

echo "Array items and indexes:" #      
for index in ${!array[*]}
do
    printf "%4d: %s\n" $index ${array[$index]}
done


Running the script will generate the following output:



Array size: 5



Array items:



one

two

three

four

five



Array indexes:



0

1

2

3

5



Array items and indexes:



0: one

1: two

2: three

3: four

5: five



Note that the "@" character can be used instead of "*" in constructs like {arr [*]}, the result will be the same except for the expansion of the quoted entry. "$ *" and "$ @" will output quoted entries, "$ {arr [*]}" will return each entry as one word, "$ {arr [@]}" will return each entry as separate words.



The following example will show how quotes and unquoted constructs return strings (especially important when these strings contain spaces):



#!/bin/bash

array=("first item" "second item" "third" "item")

echo "Number of items in original array: ${#array[*]}"
for ix in ${!array[*]}
do
    printf "   %s\n" "${array[$ix]}"
done
echo

arr=(${array[*]})
echo "After unquoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
    printf "   %s\n" "${arr[$ix]}"
done
echo

arr=("${array[*]}")
echo "After * quoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
    printf "   %s\n" "${arr[$ix]}"
done
echo

arr=("${array[@]}")
echo "After @ quoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
    printf "   %s\n" "${arr[$ix]}"
done


Output at startup:



Number of items in original array: 4



first item

second item

third

item



After unquoted expansion: 6



first

item

second

item

third

item



After * quoted expansion: 1



first item second item third item



After @ quoted expansion: 4



first item

second item

third

item



All Articles