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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |