本部分内容参考自《Linux命令行与shell脚本编程大全 第3版》。
数组变量
变量有一个很酷的特性就是,它们可作为数组使用。数组是能够存储多个值的变量。这些值可以单独引用,也可以作为整个数组来引用。
要给某个变量设置多个值,可以把值放在括号里,值与值之间用空格分隔。
$ mytest=(one two three four five)
没什么特别的地方。如果你想把数组像普通的变量那样显示,你会失望的。
$ mytest=(one two three four five)
$ echo $mytest
one
只有数组的第一个值显示出来了。要引用一个单独的数组元素,就必须用代表它在数组中位置的数值索引值。索引值要用方括号括起来。
$ echo ${mytest[2]}
three
要显示整个数组变量,可用星号作为通配符放在索引值的位置。
$ echo ${mytest[*]}
one two three four five
也可以改变某个索引值位置的值。
$ mytest[2]=seven
$ echo ${mytest[*]}
one two seven four five
甚至能用 unset
命令删除数组中的某个值,但是要小心,这可能会有点复杂。看下面的例子。
$ unset mytest[2]
$ echo ${mytest[*]}
one two four five
$ echo ${mytest[2]}
$ echo ${mytest[3]}
four
这个例子用 unset
命令删除在索引值为 2
的位置上的值。显示整个数组时,看起来像是索引里面已经没这个索引了。但当专门显示索引值为 2
的位置上的值时,就能看到这个位置是空的。
最后,可以在 unset
命令后跟上数组名来删除整个数组。
$ unset mytest
$ echo ${mytest[*]}
有时数组变量会让事情很麻烦,所以在 shell 脚本编程时并不常用。对其他 shell 而言,数组变量的可移植性并不好,如果需要在不同的 shell 环境下从事大量的脚本编写工作,这会带来很多不便。
向函数传递数组参数
向脚本函数传递数组变量的方法会有点不好理解。将数组变量当作单个参数传递的话,它不会起作用。
$ cat test9.sh
#!/bin/bash
function testit {
echo "The parameters are: $@"
thisarray=$1
echo "The received array is ${thisarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
testit $myarray
$ ./test9.sh
The original array is: 1 2 3 4 5
The parameters are: 1
The received array is 1
如果你试图将该数组变量作为函数参数,函数只会取数组变量的第一个值。
要解决这个问题,你必须将该数组变量的值分解成单个的值,然后将这些值作为函数参数使用。在函数内部,可以将所有的参数重新组合成一个新的变量。下面是个具体的例子。
$ cat test10.sh
#!/bin/bash
function testit {
local newarray
newarray=(`echo "$@"`)
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}
$ ./test10.sh
The original array is 1 2 3 4 5
The new array value is: 1 2 3 4 5
该脚本用 $myarray
变量来保存所有的数组元素,然后将它们都放在函数的命令行上。该函数随后从命令行参数中重建数组变量。在函数内部,数组仍然可以像其他数组一样使用。
$ cat test11.sh
#!/bin/bash
function addarray {
local sum=0
local newarray
newarray=($(echo "$@"))
for value in ${newarray[*]}
do
sum=$[ $sum + $value ]
done
echo $sum
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
arg1=$(echo ${myarray[*]})
result=$(addarray $arg1)
echo "The result is $result"
$ ./test11.sh
The original array is: 1 2 3 4 5
The result is 15
addarray
函数会遍历所有的数组元素,将它们累加在一起。你可以在 myarray
数组变量中放置任意多的值,addarry
函数会将它们都加起来。
从函数返回数组
从函数里向 shell 脚本传回数组变量也用类似的方法。函数用 echo
语句来按正确顺序输出单个数组值,然后脚本再将它们重新放进一个新的数组变量中。
$ cat test12.sh
#!/bin/bash
function arraydblr {
local origarray
local newarray
local elements
local i
origarray=($(echo "$@"))
newarray=($(echo "$@"))
elements=$[ $# - 1 ]
for (( i = 0; i <= $elements; i++ ))
{
newarray[$i]=$[ ${origarray[$i]} * 2 ]
}
echo ${newarray[*]}
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
arg1=$(echo ${myarray[*]})
result=($(arraydblr $arg1))
echo "The new array is: ${result[*]}"
$ ./test12.sh
The original array is: 1 2 3 4 5
The new array is: 2 4 6 8 10
该脚本用 $arg1
变量将数组值传给 arraydblr
函数。 arraydblr
函数将该数组重组到新的数组变量中,生成该输出数组变量的一个副本。然后对数据元素进行遍历,将每个元素值翻倍,并将结果存入函数中该数组变量的副本。
arraydblr
函数使用 echo
语句来输出每个数组元素的值。脚本用 arraydblr
函数的输出来重新生成一个新的数组变量。
练习
1、生成 10 个随机数保存于数组中,并找出其最大值和最小值。
#!/bin/bash
#
declare -a rand
declare -i max=0
for i in {0..9};do
rand[i]=$RANDOM
echo ${rand[$i]}
[ ${rand[$i]} -gt $max ] && max=${rand[$i]}
done
echo "Max:$max"
2、定义一个数组,数组中的元素是 /var/log
目录下所有以 .log
结尾的文件,要统计其下标为偶数的文件中的行数之和。
#!/bin/bash
declare -a files
files=(/var/log/*.log)
declare -i lines=0
for i in $(seq 0 $[${#files[*]}-1]);do
if [ $[$i%2] -eq 0 ];then
let lines+=$(wc -l ${files[$i]} | cut -d' ' -f1)
fi
done
echo "Lines:$lines"
3、生成 10 个随机数存于数组中,升序排序。
#!/bin/bash
declare -a nums
declare -i t
for i in {0..9};do
nums[$i]=$RANDOM
echo ${nums[$i]}
done
for ((i=0;i<${#nums[@]};i++));do
for ((j=${#nums[@]}-1;j>i;j--));do
if [[ ${nums[j]} -lt ${nums[j-1]} ]];then
t=${nums[j]}
nums[j]=${nums[j-1]}
nums[j-1]=$t
fi
done
done
echo "排序后:${nums[@]}"
评论区