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]#
posted @ 2021-04-09 20:35  临江仙我亦是行人  阅读(130)  评论(0编辑  收藏  举报