Bash Arrays: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 212: Line 212:
  declare -A my_assoc_array
  declare -A my_assoc_array


This command does not create the associative array immediately, it just sets an attribute on the name "my_assoc_array" which allows assignments to the name as an associative array. The array does not exist until the first assignment.  
This command does not create the associative array immediately, it just sets an attribute on the name "my_assoc_array" which allows assignments to the name as an associative array. The array does not exist until the first assignment. The fact that a specific array was declared can be tested by executing <code>declare -A</code> and grepping the result, as shown [[#Associative_Array_Declaration_Test|below]].


 
All previously declared (and not yet unset) associative arrays can be listed with:
 
 
Previously declared associative arrays can be listed with:


  declare -A
  declare -A
Line 227: Line 224:
==Associative Array Declaration Test==
==Associative Array Declaration Test==


<syntaxhighlight lang='bash'>
declare -A | grep -q "declare -A my_assoc_array" && echo "array was declared" || echo "array was not declared"
</syntaxhighlight>


==Associative Array Existence Test==
==Associative Array Existence Test==

Revision as of 21:49, 13 December 2019

External

Internal

Indexed Arrays

External

Indexed Arrays Overview

bash indexed arrays are 0-based and unidimensional. No explicit declaration is necessary if at least one element is initialized as described below.

Indexed arrays behave as local variables: an array declared in a function will be accessible to the declaring function and all functions invoked from the declaring function after declaration, but not to callers of the declaring function. In other words, indexed arrays are accessible only in the declaring scope and sub-scopes.

Indexed Arrays Declaration

Arrays do not need explicit declarations, they will be automatically declared upon the first assignment of any of their elements:

my_array_var[0]="something"

They can be explicitly declared, though:

declare -a my_array_var

Previously declared arrays can be listed with:

declare -a

Whether a specific array was declared can be checked as follows:

if declare -a | grep -q my_array_var; then
   # 'my_array_var' was declared
   ...
else
   # 'my_array_var' was not declared
   ...
fi

Negation also works:

if ! declare -a | grep -q my_array_var; then
   # 'my_array_var' was not declared
   ...
else
   # 'my_array_var' was declared   
   ...
fi


An array variable can be "undeclared" with the "unset" builtin.

unset my_array_var

Individual array elements can also be unset:

unset my_array_var[subscript] 

A subscript of "*" or "@" also removes the entire array.

Indexed Arrays Assignment

Assign Indexed Array Individual Elements

Individual elements are initialized by using ${var-name[index]}=value notation:

a[0]="something"

Entire Indexed Array

The (value ...) or ([index]=value ...) syntax can be used to initialize an entire array. The values must be separated by space:

a=("X" "Y" "Z")

If we want initialize only specific elements, we can use this syntax:

a=([0]="X" [4]="Y" [8]="Z")

Append Array Elements

Use the += operator:

declare -a my_array
my_array+=(a)
my_array+=(b)
my_array+=(c)

Indexed Arrays Reference

Reference Individual Indexed Array Elements

Element arrays can be referenced with ${var-name[index]} notation:

echo ${a[0]}

If the array variable was not previously declared, or if the specific element was not initialized, a reference attempt will return the blank string.

Reference All Indexed Array Elements

If '@' or '*' is used as subscript, the following expressions expand to all members of the array:

${var_name[@]}
${var_name[*]}

Reference a Sub-Array

A contiguous sub-array can be referenced as follows:

${var_name[@]:from}

returns all elements of the array starting with the index 'from'.

${var_name[@]:from:to}

returns all elements of the array starting with the index 'from' up to index 'to'.

Length of an Indexed Array

${#var_name[@]}
${#var_name[*]}

If the array is sparse, this does not return the index of last element plus one, but just the number of non-empty elements.

Iterate over an Indexed Array

Using the Indexed Array Elements

for i in ${array_var[@]}; do
   ...
done

Using the Index

i=0
while [[ ${i} < ${#array_var[@]} ]]; do
  echo ${array_var[$i]}
  ((i++))
done

Note that this does not work when the array is sparse, because ${#array_var[@]} only returns the number of non-empty elements, and not the array length.

Clear an Indexed Array

Note that re-declared an indexed array does not clear it. To be cleared, the array needs to be unset and redeclared.

declare -a A
...
unset A
declare -a A

Indexed Array Use Cases

Read the Content of a File into An Indexed Array

Each line will be assigned to an element of the array:

readarray < ./somefile.txt -t my_array_var

Assign Words Read from stdin to an Indexed Array

Assing words read from stdin to an array:

read -a

Iterate Over the Argument List

args=("$@")
for arg in ${args[@]}; do
  ...
done

Load an Array from a Space-Separated List

local space_separated_list="a b c d"
    
declare -a my_array

for i in ${space_separated_list}; do
    my_array+=(${i})
done

echo "length: ${#my_array[@]}"
echo ${my_array[0]}
echo ${my_array[1]}
echo ${my_array[2]}
echo ${my_array[3]}

Associative Arrays

Associative Array Overview

Associative arrays can be used to implement sets and maps in bash. The most common usage as set is to insert elements whose subscript is identical with the value.

Associative Array Declaration


Associative arrays must be explicitly declare before initialization, otherwise unexpected behavior may occur. For example, if multiple assignments are declared, only the last one is reflected in the state of the array. This is different from the behavior of the indexed arrays, which can be used without explicit declaration.

declare -A my_assoc_array

This command does not create the associative array immediately, it just sets an attribute on the name "my_assoc_array" which allows assignments to the name as an associative array. The array does not exist until the first assignment. The fact that a specific array was declared can be tested by executing declare -A and grepping the result, as shown below.

All previously declared (and not yet unset) associative arrays can be listed with:

declare -A

An associative array variable can be "undeclared" with the "unset" builtin.

unset my_assoc_array

Associative Array Declaration Test

declare -A | grep -q "declare -A my_assoc_array" && echo "array was declared" || echo "array was not declared"

Associative Array Existence Test

[[ -v my_assoc_array[@] ]] && echo "'my_assoc_array' is declared"

Also see:

-v

Associative Array Assignment

Assign Individual Associative Array Elements

Individual elements are initialized by using ${var-name[key]}=value notation:

a["color"]="blue"

The associative array variable must be declared with -A before, otherwise only the last assignment is reflected in the state of the array.

Entire Associative Array

The (["key"]="value" ...) syntax can be used to initialize an entire array. The values must be separated by space:

a=(["color]="red" ["size"]="small")

Associative Array Reference

Reference Individual Associative Array Elements

Element arrays can be referenced with ${var-name[key]} notation:

echo ${a["color"]}

If the array variable was not previously declared, or if the specific element was not initialized, a reference attempt will return the blank string.

Get All Associative Array Keys

The keys are accessed with:

${!array_var_name[@]}

Get All Associative Array Values

If '@' or '*' is used as subscript, the following expressions expand to all values maintained in the array:

${array_var_name[@]}
${array_var_name[*]}

Iterate over Key/Values of an Associative Array

for i in "${!array_var_name[@]}" do
    echo "key: ${i}"
    echo "value: ${array_var_name[${i}]}"
done

Size

${#var_name[@]}
${#var_name[*]}