网站搜索

在 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 系统中许多后台脚本的开发铺平了道路。