shell数组
1. 数组介绍
变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量的集合
简单的说,数组就是相同数据类型的元素按一定的顺序排列的集合
数组就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字为数组名,编号为数组的下标
组成数组的各个变量成为数组的分量,也成为数组的元素,有时成为下标变量
数组名和索引
-
索引的编号从0开始,属于数值索引
-
索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash4.0版本之后开始支持
-
bash的数组支持稀疏格式(索引不连续)
2. 声明数组
# 普通数组可以不事先声明,直接使用
declare -a ARRAY_NAME
# 关联数组必须先声明,再使用
declare -A ARRAY_NAME
注意:两者不可相互转换
3. 数组赋值
数组元素的赋值
3.1 一次只赋值一个元素
直接通过数组名[下标]就可以对其进行引用赋值,如果下标不存在,自动添加一个新的数组元素,如果存在就覆盖原来的值
ARRAY_NAME[INDEX]=VALUE
示例
array[0]=a
array[1]=b
array[2]=c # key可以不是连续的
weekdays[0]="Sunday"
weekdays[4]="Thursday"
3.2 一次赋值全部元素
ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)
示例
array=(1 2 3) # 数组定义, 一对括号表示是数组,数组元素用“空格”符号分隔开,默认从0开始计算下标
title=("ceo" "coo" "cto")
num=({0..10})
alpha=({a..g})
file=( *.sh )
3.3 只赋值特定元素
ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...)
示例:
array=([1]=one [2]=two [3]=three)
echo ${#array[*]}
echo ${array[*]}
3.4 交互式数组值对赋值
read -a ARRAY
示例
array=($(ls))
echo ${array[*]}
echo ${#array[*]}
示例
[root@centos8 ~]#declare -A course
[root@centos8 ~]#declare -a course
-bash: declare: course: cannot convert associative to indexed array
[root@centos8 ~]#file=( *.sh )
[root@centos8 ~]#declare -A file
-bash: declare: file: cannot convert indexed to associative array
[root@centos8 ~]#
示例
[root@centos8 ~]#i=a
[root@centos8 ~]#j=1
[root@centos8 ~]#declare -A arr
[root@centos8 ~]#arr[$i$j]=song
[root@centos8 ~]#j=2
[root@centos8 ~]#arr[$i$j]=wang
[root@centos8 ~]#echo ${arr[*]}
wang song
[root@centos8 ~]#echo ${arr[a1]}
song
[root@centos8 ~]#echo ${arr[a2]}
wang
[root@centos8 ~]#
4. 显示所有数组
显示所有数组
declare -a
示例
[root@centos8 ~]#declare -a
declare -a BASH_ARGC=()
declare -a BASH_ARGV=()
declare -a BASH_COMPLETION_VERSINFO=([0]="2" [1]="7")
declare -a BASH_LINENO=()
declare -ar BASH_REMATCH=()
declare -a BASH_SOURCE=()
declare -ar BASH_VERSINFO=([0]="4" [1]="4" [2]="19" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
declare -a DIRSTACK=()
declare -a FUNCNAME
declare -a GROUPS=()
declare -a PIPESTATUS=([0]="0")
declare -a file=([0]="for1.sh" [1]="for2.sh" [2]="for3.sh" [3]="sum.sh" [4]="while_read_check_dos.sh" [5]="while_read_passwd.sh")
[root@centos8 ~]#
5. 引用数组
5.1 引用数组元素
${ARRAY_NAME[INDEX]}
#如果省略[INDEX]表示引用下标为0的元素
示例
[root@centos8 ~]#declare -a title=([0]="ceo" [1]="coo" [2]="cto")
[root@centos8 ~]#echo ${title[1]}
coo
[root@centos8 ~]#echo ${title}
ceo
[root@centos8 ~]#echo ${title[2]}
cto
[root@centos8 ~]#echo ${title[3]}
[root@centos8 ~]#
示例
# 打印数组元素
echo ${array[0]} # 下标为 0 的内容
echo ${array[1]} # 下标为 1 的内容
echo ${array[2]} # 下标为 2 的内容
5.2 引用数组所有元素
# 打印全部数组
echo ${ARRAY_NAME[*]}
echo ${ARRAY_NAME[@]}
示例
[root@centos8 ~]#echo ${title[@]}
ceo coo cto
[root@centos8 ~]#echo ${title[*]}
ceo coo cto
[root@centos8 ~]#
5.3 数组长度,即数组中元素的个数
# 用 ${#数组名[@或*]} 可以得到数组的长度
echo ${#ARRAY_NAME[*]}
echo ${#ARRAY_NAME[@]}
示例
# 下标为0的内容长度
echo ${#array[0]}
[root@centos8 ~]#echo ${#title[*]}
3
[root@centos8 ~]#echo ${#title[@]}
3
[root@centos8 ~]#
6.数组的删除
直接通过unset数组[下标]可以清除相应的元素,不带下标,清除整个数组
删除数组中的某元素,会导致稀疏格式
unset ARRAY[INDEX] # 删除某个数组元素
示例
[root@centos8 ~]#echo ${title[*]}
ceo coo cto
[root@centos8 ~]#unset title[1]
[root@centos8 ~]#echo ${title[*]}
ceo cto
[root@centos8 ~]#
删除整个数组
unset ARRAY # 删除整个数组
示例
[root@centos8 ~]#echo ${title[*]}
ceo cto
[root@centos8 ~]#unset title
[root@centos8 ~]#echo ${title[*]}
[root@centos8 ~]#
7. 数组数据处理
7.1 数组切片
${ARRAY[@]:offset:number}
offset # 要跳过的元素个数
number # 要取出的元素个数
#取偏移量之后的所有元素
{ARRAY[@]:offset}
示例
[root@centos8 ~]#array=(1 2 3 4 5)
[root@centos8 ~]#echo ${array[@]:1:3}
2 3 4
[root@centos8 ~]#echo ${array[@]:3:2}
4 5
[root@centos8 ~]#
示例
[root@centos8 ~]#num=({0..10})
[root@centos8 ~]#echo ${num[*]:2:3}
2 3 4
[root@centos8 ~]#echo ${num[*]:6}
6 7 8 9 10
[root@centos8 ~]#
7.2 向数组中追加元素
ARRAY[${#ARRAY[*]}]=value
ARRAY[${#ARRAY[@]}]=value
示例
[root@centos8 ~]#num[${#num[@]}]=11
[root@centos8 ~]#echo ${#num[@]}
12
[root@centos8 ~]#echo ${num[@]}
0 1 2 3 4 5 6 7 8 9 10 11
[root@centos8 ~]#
7.3 替换
echo ${array[@]/5/6} # 把数组中的5替换成6,临时生效,原数据未被修改,和sed很像
array1=(${array[@]/5/6})
echo ${array1[@]}
示例:
array=(
songwanbo
tall me
hello world
)
for (( i=0;i<${#array[*]};i++ ))
do
echo "this is num $i,this content is ${array[$i]}"
done
echo ""
echo "array length:${#array[*]}"
示例:数组拼接
[@sjs_115_56 tmp]$ cat arr.sh
#!/bin/bash
a[1]="hello"
a[2]="sogo"
a[3]="welcome"
str=""
for s in ${a[@]}
do
str="${str} $s"
done
echo $str
[@sjs_115_56 tmp]$ sh arr.sh
hello sogo welcome
[@sjs_115_56 tmp]$
8. 关联数组
declare -A ARRAY_NAME
ARRAY_NAME=([idx_name1]='val1' [idx_name2]='val2‘...)
注意:关联数组必须先声明再调用
示例
[root@centos8 ~]#name[ceo]=song
[root@centos8 ~]#name[cto]=wang
[root@centos8 ~]#name[coo]=zhang
[root@centos8 ~]#echo ${name[ceo]}
zhang
[root@centos8 ~]#echo ${name[cto]}
zhang
[root@centos8 ~]#echo ${name[coo]}
zhang
[root@centos8 ~]#echo ${name}
zhang
[root@centos8 ~]#declare -A name
-bash: declare: name: cannot convert indexed to associative array
[root@centos8 ~]#unset name
[root@centos8 ~]#declare -A name
[root@centos8 ~]#name[ceo]=song
[root@centos8 ~]#name[cto]=wang
[root@centos8 ~]#name[coo]=zhang
[root@centos8 ~]#echo ${name[coo]}
zhang
[root@centos8 ~]#echo ${name[ceo]}
song
[root@centos8 ~]#echo ${name[cto]}
wang
[root@centos8 ~]#echo ${name[*]}
song wang zhang
[root@centos8 ~]#
示例:关联数组
[root@centos8 ~]#declare -A student
[root@centos8 ~]#student[name1]=xufengnian
[root@centos8 ~]#student[name2]=jiangni
[root@centos8 ~]#student[age1]=18
[root@centos8 ~]#student[age2]=16
[root@centos8 ~]#student[gender1]=m
[root@centos8 ~]#student[city1]=beiliang
[root@centos8 ~]#student[gender2]=f
[root@centos8 ~]#student[city2]=dachu
[root@centos8 ~]#student[gender2]=m
[root@centos8 ~]#student[name50]=pangzi
[root@centos8 ~]#student[name3]=xuyanbing
[root@centos8 ~]#for i in {1..50};do echo student[name$i]=${student[name$i]};done
student[name1]=xufengnian
student[name2]=jiangni
student[name3]=xuyanbing
student[name4]=
student[name5]=
......
student[name49]=
student[name50]=pangzi
示例:生成10个随机数保存于数组中,并找出其最大值和最小值
[root@centos8 script]#cat arr1.sh
#!/bin/bash
#
declare -i min max
declare -a nums
for ((i=0;i<10;i++))
do
nums[$i]=$RANDOM
[ $i -eq 0 ] && min=${nums[0]} && max=${nums[0]} && continue
[ ${nums[$i]} -gt $max ] && max=${nums[$i]} && continue
[ ${nums[$i]} -lt $min ] && min=${nums[$i]}
done
echo "All numbers are ${nums[*]}"
echo "Max is $max"
echo "Min is $min"
[root@centos8 script]#bash arr1.sh
All numbers are 1823 3286 18196 7239 6581 27780 25094 31022 29690 13691
Max is 31022
Min is 1823
[root@centos8 script]#
示例:编写脚本,定义一个数组,数组中的元素对应的值是/var/log目录下所有以.log结尾的文件;统计 出其下标为偶数的文件中的行数之和
[root@centos8 script]#cat arr2.sh
#!/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"
[root@centos8 script]#bash arr2.sh
Lines:5843
[root@centos8 script]#