本文参考文章:https://blog.csdn.net/taiyang1987912/article/details/39897547
1 赋值和取值
数组(Array)是一个由若干同类型变量组成的集合,数组均由连续的存储单元组成,最低地址对应于数组的第一个元素,最高地址对应于最后一个元素。Shell只支持一维数组,array[x]表示array数组的第x+1个元素,支持的最大数值标号是599 147 937 791。shell取得数组值(引用数组元素)格式是:${array[x]}。
#!/bin/bash
city[0]=Nanjing #对第1、2个数组元素赋值
city[1]=Beijing
city[9]=Melbourne #对第10个数组元素赋值
city[15]=NewYork #对第16个数组元素赋值
echo "city[0]=${city[0]}"
echo "city[1]=${city[1]}"
echo "city[9]=${city[9]}"
echo "city[15]=${city[15]}"
echo "city[2]=${city[2]}" #未初始化数组的值为空
echo "city[10]=${city[10]}"
Shell中允许数组空缺元素,即可以不连续地给数组赋值。还可以用圆括号将一组值赋给数组。
#!/bin/bash
city=(Nanjing Beijing Melbourne NewYork) #圆括号内以空格为分隔符,依次赋给数组元素
echo "city[0]=${city[0]}"
echo "city[1]=${city[1]}"
echo "city[2]=${city[2]}"
echo "city[3]=${city[3]}"
echo "city[4]=${city[4]}" #未被初始化输出空
echo "city[5]=${city[5]}"
#!/bin/bash
city=(Nanjing [10]=Atlanta Massachusetts Marseilles) #指定所赋元素的标号,并以此标号为起点继续赋值
echo "city[0]=${city[0]}" #city[0]=Nanjing
echo "city[1]=${city[1]}" #city[1]=
echo "city[10]=${city[10]}" #city[10]=Atlanta
echo "city[11]=${city[11]}" #city[11]=Massachusetts
echo "city[12]=${city[12]}" #city[12]=Marseilles
echo "city[13]=${city[13]}" #city[13]=
既然圆括号内允许对数组指定元素进行赋值,那么完全可以按照任意顺序指定任意元素对数组赋值。例如:
city=([2]=Nanjing [10]=Atlanta [1]=Massachusetts [5]=Marseilles)
位置参数
位置参数中$@和$*都表示传递到脚本的所有参数,在数组中@和‘*的应用是打印数组的所有元素。
#!/bin/bash
city=(Nanjing Beijing Melbourne NewYork)
for i in ${city[@]} #等价于 for i in ${city[*]}
do #打印数组的所有元素
echo $i
done
#!/bin/bash
city[1]="Hong Kong" #用引号包含空格的字符串
city[100]=Massachusetts
city[101]="New York"
city[10000]=Atlanta
for i in "${city[@]}" #这里必须加"",每个元素占一行;如果不加"",中间带空格的元素如Hong Kong会被分成两行输出
do
echo $i
done
for j in "${city[*]}" #这里加"",所有元素占一行; 如果不加"",每个元素占一行
do
echo $j
done
由于city数组元素包含了空格,因此需要使用引号将${city[@]}引起来,for循环和@只打印被赋值的元素而不打印未赋值的元素(试了一下*也是只打印被赋值的元素)。
注意:用引号时,"${city[@]}“将数组的所有元素分行打印,而”${city[*]}"只能将数组的所有元素打印在一行内且中间以IFS分隔(对于for循环来说是这样;而对于直接输出,即echo “${city[@]” 或者是echo “${city[*]}”,不论加不加引号,结果都是输出在用空格分隔的一行)。
不用引号时,${city[@]}和${city[*]}是等价的,echo整个数组,输出结果到一行;而用for循环时(如上代码),输出是每个元素占一行。
数组的用法
数组的字符串操作与字符串操作的符号和意义完全一致,数组字符串操作特殊之处在于所有的操作都是针对所有的数组元素逐个进行的。
- 数组的字符串操作
#!/bin/bash
city=(Nanjing Atlanta Massachusetts MaseillesMas)
echo "Extracting Substring" #抽取字串
echo ${city[*]:0} #抽取整个数组 Nanjing Atlanta Massachusetts Marseilles
echo ${city[*]:1} #抽取从第1个元素到结束的数组 Atlanta Massachusetts Marseilles
echo ${city[*]:3} #抽取从第3个元素到结束的数组 Marseilles
echo ${city[*]:0:2} #抽取从第0个元素开始的两个元素 Nanjing Atlanta
echo
echo "Removing Substring" #删除字串
echo ${city[*]#M*a} #删除匹配M*a的最短字串 Nanjing Atlanta ssachusetts rseilles
echo ${city[*]##M*a} #删除匹配M*a的最长字串 Nanjing Atlanta chusetts rseilles
echo
echo "Replcing Substring" #替换子串功能
echo ${city[*]/M*s/Year} #替换第1次与M*a匹配的子串 Nanjing Atlanta Year Year
echo ${city[*]//Mas/Year} #替换所有与Mas匹配的子串 Nanjing Atlanta Yearsachusetts YeareillesYear
#替换的正则为最长匹配
数组也可以存放read命令所读入的用户输入参数,declare -a city(并不是必须的)将city申明为数组,用read -a city命令将输入存储到city数组之中,输入以空格分开。可以使用unset city[0]命令清空一个元素,和unset city清空整个数组。使用${#city[@]}获取数组的长度。
- 数组连接
#!/bin/bash
city=(Beijing Nanjing Shanghai)
person=(Cai [5]=Wu Tang) #数组不连续地赋值
declare -a combine #声明combine数组
combine=(${city[@]} ${person[@]}) #combine是数组city和person的连接,连接操作将不连续的元素按序存放到combine数组中
element_count=${#combine[@]} #while循环输出combine数组
index=0
while [ "$index" -lt "$element_count" ]
do
echo "Element[$index]=${combine[$index]}" #数组标号与值的对应关系
let "index=$index+1"
done
###################
echo
unset combine #清空combine数组
combine[0]=${city[@]} #将city数组赋给combine[0]的一个元素
combine[1]=${person[@]} #将person数组赋给combine[1]的一个元素
element_count=${#combine[@]}
index=0
while [ "$index" -lt "$element_count" ]
do
echo "Element[$index]=${combine[$index]}"
let "index=$index+1"
done
###################
echo
declare -a subcombine=${combine[1]} #声明数组时赋值
element_count=${#subcombine[@]}
index=0
while [ "$index" -lt "$element_count" ]
do
echo "Element[$index]=${subcombine[$index]}"
let "index=$index+1"
done