shell编程进阶之数组

数组ARRAY

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

数组:存储多个元素的连续的内存空间,相当于多个变量的集合,元素编号支持稀疏格式,即索引编号不连续。

高级变量用法 - 有类型变量

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

declare [OPTION] 变量名

-r 声明或显示只读变量

-i 声明或显示整数型变量

-a 声明或显示索引数组

-A 声明或显示关联数组

-f 显示系统的所有函数

-F 仅显示所有函数

-x 声明或显示环境变量和函数

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

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


声明数组:

declare -a ARRAY_NAME //声明索引数组,元素编号只能是数字,从0开始

declare -A ARRAY_NAME //声明关联数组,元素编号可以自定义格式,需bash4.0以上的版本才支持

declare -i ARRAY_NAME //声明整数数组,元素变量只支持整数值

declare -r ARRAY_NAME //声明只读数组

declare -l ARRAY_NAME //转换数组为小写

declare -u ARRAY_NAME //转换数组为大写

声明数组

declare -a user //声明索引数组

declare -a //查看索引数组

declare -A user //声明关联数组

declare -A

declare -i //查看所有整数数组

数组元素赋值,索引数组的编号只支持数字,而且是从0开始

1.单个元素赋值

user[0]="user0"

user[1]="user1"

user[2]="user2"

user[3]="user3"

user[4]="user4"

user[5]="user5"

2.多个元素赋值

user=("usera" "userb" "userc" "userd" ...)

3.只赋值特定元素,则其他未赋值的元素值为空,如user[1]就为空

user=([0]="usera" [3]="userc"...)

4.交互式赋值

read -a user

a b c d e //输入的参数以空格隔开

a\ b cc ee //如果输入的参数包含空格则需要转义,如"a b".

显示或引用数组

declare -a

echo $user //显示一个元素,相当于echo ${user[0]}

echo ${user[0]}

echo ${user[2]}

echo ${user[3]}

echo ${user[*]}

echo ${#user[*]}

取消数组或元素

unset user[2] //取消数组元素2

unset user //取消整个数组


声明关联数组

declare -A user

数组元素赋值,编号支持字母,数字或单词

user[a]=usera

user[b]=userb

user[2]=userc

user[abc]=userabc

查看数组元素值

declare -A|tail -1

echo ${user[a]}

echo ${user[2]}

echo ${user[abc]}

取消数组或元素

unset user[a]

unset user

批量定义数组元素,未声明数组类型则认为索引数组

user=(usera userb userc userd)

echo ${user[3]}

num=({1..10})

echo ${num[8]}

echo ${num[*]} //显示数组中的所有元素,*也可用@代替

echo ${#num[*]} //显示数组的元素个数,*也可用@代替

file=({/app/bin/*.sh})

echo ${file[3]}

echo ${file[@]} //显示数组的所有元素

echo ${#file[@]} //显示数组的元素个数

num=({1..10})

for((i=0;i<${#num[@]};i++));do echo num is ${num[$i]};done

unset num[2]

for((i=0;i<${#num[@]};i++));do echo num is ${num[$i]};done //稀疏数组显示会有问题,即不会自动递归填补空值

num[2]=3 //添加缺少的数组元素

数组元素处理

数组切片:${ARRAY[@]:offset:number}

offset: 要跳过的元素个数

number: 要取出的元素个数

num=({1..10})

echo ${num[*]:2:5} //跳过前2个,取出5个元素

3 4 5 6 7

echo ${num[*]:3} //跳过前3个,取出之后的所有元素

4 5 6 7 8 9 10 11 12 13

seq 10 //显示1..10,认从1开始到指定数字

seq 2 5 //显示2,3,4,5,显示从起始值到结束值之间的数字

seq 1 2 10 //显示1,5,7,9,格式为起始值,增量值,结束值

num=10;seq 0 2 $[$num-1]

echo {1..10..2} //显示1,9,格式为起始值,结束值,增量值

num=({1..10..2})

向数组中追加元素:ARRAY[${#ARRAY[*]}]

num=({1..10})

echo ${sum[10]} 值为空

num[${#num[*]}]=11 //追加数组元素,追加到所有数组元素的最后

echo ${sum[10]} 显示追加的元素值11

num[${#num[*]}]=12 //可追加多次

num[${#num[*]}]=13

删除数组中的某元素,会导致稀疏格式:unset ARRAY[INDEX]

unset num[8]

删除整个数组:unset ARRAY

unset num

字符串处理

man bash 搜索\$\{parameter\} //查看命令帮助

取字符值

注意:取值时,正数前面不需要加空格,负数前面需要加一个空格。

$alp 或${alp} 显示字符串内容

${#var} 显示字符串的长度

${var:offset:0} 显示所有字符串

${var:offset} 跳过前几个字符,取后面的所有字符

${var:offset:length} 跳过前offset个字符,取其后面的length个字符

${var:offset:-length} 跳过前offset个字符和后length个字符,显示间的内容

${var: -length} 取字符串的最右侧几个字符。注意:冒号后有一个空格,如${num: -3}

${var: -length: -offset} 取出字符串的最右侧几个字符,然后在此基础上,跳过后几个字符,显示剩余字符。

${var: -length:length} 取出字符串的最右侧的几个字符,然后在此基础上,取出length个字符

alp=`echo {a..z}|tr -d " "` //显示字符串abcdefg..xyz

echo $alp //显示字符串

echo ${#alp} //查看字符串的长度,即字符个数

echo ${alp:0} //显示所有字符串

echo ${alp:3} //跳过前3个字符,显示后面所有字符

echo ${alp:3:5} //跳过前3个字符,取其后面的5个字符,显示defgh

echo ${alp:3:-5} //跳过前3个字符和后5个字符,显示间的内容

echo ${alp: -3} //显示最后3个字符,即xyz

echo ${alp: -3: -2} //先取出最右侧的3个字符,然后再跳过后2个字符,即最后显示字符x。

echo ${alp: -3:2} //先取出最右侧的3个字符,然后取出前2个字符,即显示为xy

删除字符

${var#word} //删除指定的前缀字符

${var#*word} //从左往右,匹配删除word本身及word之前的所有字符

${var##*word} //贪婪模式,匹配删除最后的word本身及之前的所有字符

${var%word} //删除指定的后缀字符

${var%word*} //从右往左,匹配删除word本身及word之后的所有字符。注意写法*号在word右边

${var%%word*} //贪婪模式,匹配删除最后的word本身及之后的所有字符

url=http://www.baidu.com:80

echo ${url#http://}

echo ${url#*:}

echo ${url##*:} //取端口号

echo ${url%:80}

echo ${url%:*} //取网址

echo ${url%%:*} //取协议

取路径和文件

file="/var/log/messages"

echo ${file#*/} //取相对路径:var/log/messages

echo ${file##*/} //取文件名:messages,相当于basename

echo ${file%/*} //取父目录:/var/log,相当于dirname

查找替换

${var/pattern/string} //查找并替换第一次被匹配到的字符

${var//pattern/string} //查找并替换所有被匹配到的字符

${var/#pattern/string} //查找并替换行首匹配到的字符

${var/%pattern/string} //查找并替换行尾匹配到的字符

a=abcabc

echo ${a/b/g} //匹配替换一次,显示为agcabc

echo ${a//a/g} //匹配替换所有,显示为gbcgbc

echo ${a/#a/g} //匹配替换行首,显示为gbcabc

echo ${a/%c/g} //匹配替换行尾,显示为abcabg

url=http://www.baidu.com:80

echo ${url/%80/8080} //替换端口为8080

查找删除

${var/pattern} //查找并删除第一次匹配到的字符

${var//pattern} //查找并删除所有匹配到的字符

${var/#pattern} //查找并删除行首匹配到的字符

${var/%pattern} //查找并删除行尾匹配到的字符

a=abcabc

echo ${a/b} //显示为acabc

echo ${a//b} //acac

echo ${a/#a} //bcabc

echo ${a/%c} //abcab

转换大小写

${var^} //转换首字母为大写

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

${var,} //转换首字母为小写

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

a=abcabc

b=ABCABC

echo ${a^^} //小写转大写

echo ${b,} //大写转小写

变量赋值检测

${var:-word} 如果var值为空或未设置,则返回word值,否则返回之前设置的var值

${var:+word} 如果var值为空或未设置,则返回为空,否则返回word值

${var:=word} 如果var值为空或未设置,则设置var值为word值,即定义变量值,否则返回之前设置的var值

${var:?word} 如果var值为空或未设置,则返回错误信息word,否则返回之前设置的var值

a=abc

b=

echo ${a:-c} 显示abc

echo ${b:-c} 显示c

echo ${a:+c} 显示c

echo ${b:+c} 显示为空

echo ${a:=c} 显示为abc

echo ${b:=c} 显示为c,并赋值给b

echo $b 显示为c,即上述赋值生效

unset b

echo ${a:?c} 或 echo ${a:?} 显示abc

#echo ${b:?} 未定义则显示如下的错误信息

-bash: b: parameter null or not set

#echo ${b:?this is error} 错误信息显示自定义的语句或值

-bash: b: this is error

#echo ${b:?100}

-bash: b: 100

为所有脚本使用一个独立的变量文件,统一所有变量,类似于独立的函数文件

echo "name=user1" > var //将所有的变量都放到文件var中,以后的脚本都调用此变量文件即可

vi a.sh

#!/bin/bash

#a.sh

. var

echo your name is $name

执行./a.sh

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

cmd=whoami

# echo $cmd

whoami

# echo `$cmd`

# $cmd

# eval $cmd

echo `whoami`

eval whoami

echo `ll`

eval ll //保留源命令属性显示的格式等

n=10

echo {1..$n} //无法正常显示序列

eval echo {1..$n} //正常显示数字序列1-10

间接变量引用

如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用

两种方式:eval var1=\$$var2 或 var1=${!var2}

a=b

b=c

eval echo \$$a //显示为c

echo ${!a} //显示为c

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...