在 Linux Shell 脚本中使用数组 – 第 8 部分
我们无法想象没有数组概念的编程语言。它们在不同语言之间如何实现并不重要。相反,数组帮助我们将相似或不同的数据合并到一个符号名称下。
由于我们关心的是 shell 脚本,本文将帮助您尝试一些利用数组概念的 shell 脚本。
数组初始化和使用
在较新版本的 bash 中,它支持一维数组。数组可以通过 shell 内置的 declare 显式声明。
declare -a var
但没有必要像上面那样声明数组变量。我们可以直接将单个元素插入到数组中,如下所示。
var[XX]=<value>
其中“XX”表示数组索引。要取消引用数组元素,请使用大括号语法,即
${var[XX]}
注意:数组索引始终从 0 开始。
初始化整个数组的另一种便捷方法是使用一对括号,如下所示。
var=( element1 element2 element3 . . . elementN )
还有另一种为数组赋值的方法。这种初始化方式是前面解释的方法的子类。
array=( [XX]=<value> [XX]=<value> . . . )
我们还可以在执行期间使用 shell 内置的 read 读取数组/为其赋值。
read -a array
现在,在脚本内执行上述语句后,它会等待一些输入。我们需要提供用空格(而不是回车符)分隔的数组元素。输入值后按 Enter 键终止。
为了遍历数组元素,我们还可以使用 for 循环。
for i in “${array[@]}”
do
#access each element as $i. . .
done
以下脚本总结了该特定部分的内容。
#!/bin/bash
array1[0]=one
array1[1]=1
echo ${array1[0]}
echo ${array1[1]}
array2=( one two three )
echo ${array2[0]}
echo ${array2[2]}
array3=( [9]=nine [11]=11 )
echo ${array3[9]}
echo ${array3[11]}
read -a array4
for i in "${array4[@]}"
do
echo $i
done
exit 0
数组上的各种操作
许多标准字符串操作都适用于数组。看下面的示例脚本,它实现了对数组的一些操作(包括字符串操作)。
#!/bin/bash
array=( apple bat cat dog elephant frog )
#print first element
echo ${array[0]}
echo ${array:0}
#display all elements
echo ${array[@]}
echo ${array[@]:0}
#display all elements except first one
echo ${array[@]:1}
#display elements in a range
echo ${array[@]:1:4}
#length of first element
echo ${#array[0]}
echo ${#array}
#number of elements
echo ${#array[*]}
echo ${#array[@]}
#replacing substring
echo ${array[@]//a/A}
exit 0
以下是执行上述脚本时产生的输出。
apple
apple
apple bat cat dog elephant frog
apple bat cat dog elephant frog
bat cat dog elephant frog
bat cat dog elephant
5
5
6
6
Apple bAt cAt dog elephAnt frog
我认为详细解释上面的脚本没有意义,因为它是不言自明的。如果有必要,我将在本系列中专门讨论字符串操作的一部分。
用数组替换命令
命令替换将一个命令或多个命令的输出分配到另一个上下文中。在数组的上下文中,我们可以将命令的输出作为数组的单个元素插入。语法如下。
array=( $(command) )
默认情况下,命令输出中以空格分隔的内容将作为单独的元素插入到数组中。以下脚本列出了目录的内容,其中是具有 755 权限的文件。
#!/bin/bash
ERR=27
EXT=0
if [ $# -ne 1 ]; then
echo "Usage: $0 <path>"
exit $ERR
fi
if [ ! -d $1 ]; then
echo "Directory $1 doesn't exists"
exit $ERR
fi
temp=( $(find $1 -maxdepth 1 -type f) )
for i in "${temp[@]}"
do
perm=$(ls -l $i)
if [ `expr ${perm:0:10} : "-rwxr-xr-x"` -eq 10 ]; then
echo ${i##*/}
fi
done
exit $EXT
模拟二维数组
我们可以使用一维数组轻松表示二维矩阵。在行主序中,矩阵每行中的表示元素以顺序方式逐渐存储在数组索引中。对于 mXn 矩阵,其公式可以写为:
matrix[i][j]=array[n*i+j]
查看另一个示例脚本,用于添加 2 个矩阵并打印结果矩阵。
#!/bin/bash
read -p "Enter the matrix order [mxn] : " t
m=${t:0:1}
n=${t:2:1}
echo "Enter the elements for first matrix"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
read x[$(($n*$i+$j))]
done
done
echo "Enter the elements for second matrix"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
read y[$(($n*$i+$j))]
z[$(($n*$i+$j))]=$((${x[$(($n*$i+$j))]}+${y[$(($n*$i+$j))]}))
done
done
echo "Matrix after addition is"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
echo -ne "${z[$(($n*$i+$j))]}\t"
done
echo -e "\n"
done
exit 0
尽管在 shell 脚本内实现数组存在限制,但它在少数情况下变得有用,特别是当我们处理命令替换时。从管理的角度来看,数组的概念为 GNU/Linux 系统中许多后台脚本的开发铺平了道路。