1. Arrays
Arrays are variables that hold more than one value at a time.
-
Getting started:
a[0]=fooecho ${a[0]}days=(Sun Mon Tue Wed Thu Fri Sat)echo ${days[0]}echo ${days[*]}echo $days[*]echo $daysIf no index is given, the first item is returned.
days=([0]=Sun [1]=Mon [2]=Tue [3]=Wed [4]=Thu [5]=Fri [6]=Sat)echo ${days[*]} -
Let's see an example that counts files by modification time and shows them in a table. Such a script could be used to determine when a system is most active.
./hours.sh./hours.sh /usr/bin/vim hours.shhours.sh#!/bin/bash
# hours: script to count files by modification time
usage () {
echo "usage: ${0##*/} directory" >&2
}
# Check that argument is a directory
if [[ ! -d "$1" ]]; then
usage
exit 1
fi
# Initialize array
for i in {0..23}; do hours[i]=0; done
# Collect data
for i in $(stat -c %y "$1"/* | cut -c 12-13); do
j="${i#0}"
((++hours[j]))
((++count))
done
# Display data
echo -e "Hour\tFiles\tHour\tFiles"
echo -e "----\t-----\t----\t-----"
for i in {0..11}; do
j=$((i + 12))
printf "%02d\t%d\t%02d\t%d\n" \
"$i" \
"${hours[i]}" \
"$j" \
"${hours[j]}"
done
printf "\nTotal files = %d\n" $countTo get the last modification time of the files we use the command
stat:stat --help | lessstat -c %y *stat -c %y * | cut -c 12-13We use the hour of modification as an index for the array.
-
Outputting the entire contents of an array:
animals=("a dog" "a cat" "a fish")for i in ${animals[*]}; do echo $i; donefor i in ${animals[@]}; do echo $i; donefor i in "${animals[*]}"; do echo $i; donefor i in "${animals[@]}"; do echo $i; doneNotice that this is similar to the behavior of the array of the positional parameters:
$*,$@,"$*","$@". -
The number of array elements:
a[100]=fooecho ${#a[@]}There is only one element in the array.
echo ${#a[100]}This is the length of the element 100.
Remember that
$#is the number of positional parameters. -
Finding the subscripts used by an array:
foo=([2]=a [4]=b [6]=c)for i in "${foo[@]}"; do echo $i; donefor i in "${!foo[@]}"; do echo $i; done -
Adding elements to the end of an array:
foo=(a b c)echo ${foo[@]}foo+=(d e f)echo ${foo[@]} -
It is not so hard to sort an array with a little bit of coding:
vim array-sort.sharray-sort.sh#!/bin/bash
# array-sort: Sort an array
a=(f e d c b a)
echo "Original array: ${a[@]}"
a_sorted=($(for i in "${a[@]}"; do echo $i; done | sort))
#a_sorted=($(echo "${a[@]}" | tr ' ' "\n" | sort))
echo "Sorted array: ${a_sorted[@]}"./array-sort.sh -
To delete an array, use the
unsetcommand:foo=(a b c d e f)echo ${foo[@]}unset fooecho ${foo[@]}It may also be used to delete single array elements.
foo=(a b c d e f)echo ${foo[@]}unset 'foo[2]'echo ${foo[@]}Notice that the array element must be quoted to prevent the shell from performing pathname expansion.
-
Notice also that the assignment of an empty value to an array does not empty its contents:
foo=(a b c d e f)foo=echo ${foo[@]}This is because any reference to an array variable without a subscript refers to element zero of the array. For example:
foo=(a b c d e f)echo ${foo[@]}foo=Aecho ${foo[@]} -
Associative arrays use strings rather than integers as array indexes:
declare -A colors
colors["red"]="#ff0000"
colors["green"]="#00ff00"
colors["blue"]="#0000ff"
Associative arrays must be created with declare -A. Its
elements are accessed in the same way as the integer indexed
arrays:
echo ${colors["green"]}