1. 数组介绍

变量:存储单个元素的内存空间

数组:存储多个元素的连续的内存空间,相当于多个变量的集合

数组名和索引:

索引(下标)的编号从0开始,属于数值索引

索引可支持使用自定义的格式,而不仅是数值格式即为关联索引,bash4.0版本之后开始支持  bash的数组支持稀疏格式(索引不连续)

#yyds干货盘点#shell脚本编程进阶之数组_数组

#yyds干货盘点#shell脚本编程进阶之数组_数组_02


声明数组 

#普通数组可以不事先声明,直接使用

declare  -a  ARRAY_NAME

#关联数组必须先声明,再使用  (下标为任意的格式)

declare  -A  ARRAY_NAME

注意:两者不可相互转换

2. 数组赋值

数组元素的赋值

(1) 一次只赋值一个元素

ARRAY_NAME[INDEX]=VALUE

weekdays[0]="Sunday"
weekdays[4]="Thursday"

(2) 一次赋值全部元素

ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)
title=("ceo" "coo" "cto")
num=({0..10})
alpha=({a..g})
file=( *.sh )

(3) 只赋值特定元素

ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...)  #稀疏格式

(4) 交互式数组值对赋值

read -a ARRAY

显示所有数组

[root@c7-147 scripts]#declare -a
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='()'
declare -ar BASH_REMATCH='()'
declare -a BASH_SOURCE='()'
declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [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 weekdays='([0]="Sunday" [4]="Thursday")'

[root@c7-147 scripts]#echo ${weekdays}
Sunday
[root@c7-147 scripts]#echo ${weekdays[0]}
Sunday
[root@c7-147 scripts]#echo ${weekdays[4]}
Thursday
[root@c7-147 scripts]#echo ${weekdays[*]}
Sunday Thursday
[root@c7-147 scripts]#echo ${weekdays[@]}
Sunday Thursday

一次赋值所有

#yyds干货盘点#shell脚本编程进阶之数组_数组_03

#yyds干货盘点#shell脚本编程进阶之数组_赋值_04

#yyds干货盘点#shell脚本编程进阶之数组_数组_05


将所有.sh结尾的文件组成一个数组

#yyds干货盘点#shell脚本编程进阶之数组_数组_06

#yyds干货盘点#shell脚本编程进阶之数组_数组_07

一群数字组成一个数组

#yyds干货盘点#shell脚本编程进阶之数组_赋值_08

3. read -a 定义数组

#yyds干货盘点#shell脚本编程进阶之数组_赋值_09

4.关联数组

以下的由于未声明declare  -A  ARRAY_NAME,所以乱套

#yyds干货盘点#shell脚本编程进阶之数组_bash_10

#yyds干货盘点#shell脚本编程进阶之数组_赋值_11

关联数组组合相关数据

#yyds干货盘点#shell脚本编程进阶之数组_bash_12

#yyds干货盘点#shell脚本编程进阶之数组_bash_13

#yyds干货盘点#shell脚本编程进阶之数组_赋值_14

5. 数组数据处理

数组切片:

${ARRAY[@]:offset:number}

offset #要跳过的元素个数

number #要取出的元素个数

#取偏移量之后的所有元素

{ARRAY[@]:offset}

[root@c7-147 scripts]#num=({0..10})
[root@c7-147 scripts]#echo ${num[*]:2:3}
2 3 4
[root@c7-147 scripts]#echo ${num[*]:6}
6 7 8 9 10

#yyds干货盘点#shell脚本编程进阶之数组_bash_15

数组的添加值和删除值

#yyds干货盘点#shell脚本编程进阶之数组_赋值_16

生成10个随机数保存于数组中,并找出其最大值和最小值

#yyds干货盘点#shell脚本编程进阶之数组_bash_17

6. 字符串处理

基于偏移量取字符串

#yyds干货盘点#shell脚本编程进阶之数组_数组_18


#返回字符串变量var的长度   ${#var}

#返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0  ${#var}-1 之间(bash4.2后,允许为负值)

${var:offset}

#返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分  ${var:offset:number}

#取字符串的最右侧几个字符,取字符串的最右侧几个字符, 注意:冒号后必须有一空白字符

${var: -length}

#从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字符之前的内容,:掐头去尾

${var:offset:-length}

#yyds干货盘点#shell脚本编程进阶之数组_bash_19

#先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容,注意:-length前空格     ${var: -length:-offset}

#yyds干货盘点#shell脚本编程进阶之数组_数组_20


基于模式取子串

#其中word可以是指定的任意字符,自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字符串(含)之间的所有字符

${var#*word}

#同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容${var##*word}

[root@c7-147 ~]#file="var/log/messages"
[root@c7-147 ~]#echo ${file#*/} 从前往后删,删到第一个斜线
log/messages
[root@c7-147 ~]#echo ${file##*/} 从前往后,贪婪模式
messages

#其中word可以是指定的任意字符,功能:自右而左,查找var变量所存储的字符串中,第一次出现的word,删除字符串最后一个字符向左至第一次出现word字符串(含)之间的所有字符

${var%word*}

#同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符

${var%%word*}

[root@c7-147 ~]#file="var/log/messages"
[root@c7-147 ~]#echo ${file%/*} #从右边往左删
var/log
[root@c7-147 ~]#echo ${file%%/*} #贪婪模式从右往左
var
[root@c7-147 ~]#url=http://www.magedu.com:8080
[root@c7-147 ~]#echo ${url##*:}
8080
[root@c7-147 ~]#echo ${url%%:*}
http

查找替换

#查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之

${var/pattern/substr}

#查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substr替换之

${var//pattern/substr}

#查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替换之

${var/#pattern/substr}

#查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替换之

${var/%pattern/substr}

查找并删除

#删除var表示的字符串中第一次被pattern匹配到的字符串

${var/pattern}

删除var表示的字符串中所有被pattern匹配到的字符串

${var//pattern}

删除var表示的字符串中所有以pattern为行首匹配到的字符串

${var/#pattern}

删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串

${var/%pattern}

字符大小写转换

#把var中的所有小写字母转换为大写
${var^^}

#把var中的所有大写字母转换为小写
${var,,}

#yyds干货盘点#shell脚本编程进阶之数组_bash_21

7. 高级变量赋值

#yyds干货盘点#shell脚本编程进阶之数组_赋值_22

#yyds干货盘点#shell脚本编程进阶之数组_数组_23

[root@centos8 ~]#title=ceo
[root@centos8 ~]#name=${title:-mage}
[root@centos8 ~]#echo $name
ceo

[root@centos8 ~]#title=
[root@centos8 ~]#name=${title:-mage}
[root@centos8 ~]#echo $name
mage

[root@centos8 ~]#unset title
[root@centos8 ~]#name=${title:-mage}
[root@centos8 ~]#echo $name
mage

#yyds干货盘点#shell脚本编程进阶之数组_数组_24

8. 高级变量用法有类型变量

Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令用于指定变量的类型,两个命令是等价的

declare [选项] 变量名

选项:

-r 声明或显示只读变量

-i 将变量定义为整型数

-a 将变量定义为数组

-A 将变量定义为关联数组

-f 显示已定义的所有函数名及其内容

-F 仅显示已定义的所有函数名

-x 声明或显示环境变量和函数,相当于export

-l 声明变量为小写字母 declare –l var=UPPER

-u 声明变量为大写字母 declare –u var=lower

9. 变量间接引用 eval

eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量,该命令对变量进行两次扫描

[root@centos8 ~]# CMD=whoami
[root@centos8 ~]# echo $CMD
whoami
[root@centos8 ~]# eval $CMD
root

[root@centos8 ~]# n=10
[root@centos8 ~]# echo {0..$n}
{0..10}
[root@centos8 ~]# eval echo {0..$n}
0 1 2 3 4 5 6 7 8 9 10

[root@centos8 ~]#for i in `eval echo {1..$n}` ;do echo i=$i ;done
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10


[root@centos8 ~]#i=1
[root@centos8 ~]#j=a
[root@centos8 ~]#$j$i=hello
-bash: a1=hello: command not found
[root@centos8 ~]#eval $j$i=hello
[root@centos8 ~]#echo $j$i
a1

#yyds干货盘点#shell脚本编程进阶之数组_赋值_25

10. 间接变量引用

如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用variable1的值是variable2,而variable2又是变量名,variable2的值为value,间接变量引用是指通过variable1获得变量值value的行为

variable1=variable2

variable2=value

bash Shell提供了两种格式实现间接变量引用

eval tempvar=\$$variable1

tempvar=${!variable1}

[root@centos8 ~]#ceo=name
[root@centos8 ~]#name=mage
[root@centos8 ~]#echo $ceo
name
[root@centos8 ~]#echo $$ceo
33722ceo
[root@centos8 ~]#echo $BASHPID
33722
[root@centos8 ~]#echo \$$ceo
$name
[root@centos8 ~]#eval tmp=\$$ceo
[root@centos8 ~]#echo $tmp
mage
#方法二:
[root@centos8 ~]#echo ${!ceo}
mage

[root@server ~]# NAME=wangxiaochun
[root@server ~]# N=NAME
[root@server ~]# N1=${!N}
[root@server ~]# echo $N1
wangxiaochun

[root@server ~]# eval N2=\$$N
[root@server ~]# echo $N2
wangxiaochun

11. 变量引用reference

help test

#yyds干货盘点#shell脚本编程进阶之数组_赋值_26

[root@centos8 ~]#cat test.sh
#!/bin/bash
ceo=mage
title=ceo
declare -n ref=$title
[-R ref ] && echo reference echo $ref
ceo=wang
echo $ref
[root@centos8 ~]#bash test.sh
reference
mage
wang

help declare  

#yyds干货盘点#shell脚本编程进阶之数组_bash_27

-n 定义是变量引用