(八)shell编程之数组,字符串还有高级变量
2021/6/14 7:21:07
本文主要是介绍(八)shell编程之数组,字符串还有高级变量,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
数组 array
数组介绍
变量:存储单个元素的内存空间 数组:存储多个元素的连续的内存空间,相当于多个变量的集合 数组名和索引 索引的编号从0开始,属于数值索引 索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash 4.0版本之后开始支持 bash的数组支持稀疏格式(索引不连续)
声明数组
#普通数组可以不事先声明,直接使用 declare -a ARRAY_NAME #关联数组必须先声明,再使用 declare -A ARRAY_NAME
注意:两者不可相互转换
数组赋值
数组元素的赋值
(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@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@ubuntu1804 ~]# i=a [root@ubuntu1804 ~]# j=1 [root@ubuntu1804 ~]# declare -A arr [root@ubuntu1804 ~]# arr[$i$j]=long [root@ubuntu1804 ~]# j=2 [root@ubuntu1804 ~]# arr[$i$j]=king [root@ubuntu1804 ~]# echo ${arr[*]} long king [root@ubuntu1804 ~]# echo ${arr[a1]} long [root@ubuntu1804 ~]# echo ${arr[a2]} king
显示所有数组
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")
引用数组
引用特定的数组元素
${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]}
引用数组所有元素
${ARRAY_NAME[*]} ${ARRAY_NAME[@]}
范例:
[root@centos8 ~]# echo ${title[@]} ceo coo cto [root@centos8 ~]# echo ${title[*]} ceo coo cto
数组的长度,即数组中元素的个数
${#ARRAY_NAME[*]} ${#ARRAY_NAME[@]}
范例:
[root@centos8 ~]# echo ${#title[*]} 3
删除数组
删除数组中的某元素,会导致稀疏格式
unset ARRAY[INDEX]
范例:
[root@centos8 ~]# echo ${title[*]} ceo coo cto [root@centos8 ~]# unset title[1] [root@centos8 ~]# echo ${title[*]} ceo cto
删除整个数组
unset ARRAY
范例:
[root@centos8 ~]# unset title [root@centos8 ~]# echo ${title[*]}
数组数据处理
数组切片:
${ARRAY[@]:offset:number} offset #要跳过的元素个数 number #要取出的元素个数 #取偏移量之后的所有元素 {ARRAY[@]:offset}
范例:
[root@centos8 ~]# num=({0..10}) [root@centos8 ~]# echo ${num[*]:2:3} 2 3 4 [root@centos8 ~]# echo ${num[*]:6} 6 7 8 9 10
向数组中追加元素:
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
关联数组
declare -A ARRAY_NAME ARRAY_NAME=([idx_name1]='val1' [idx_name2]='val2‘...)
注意:关联数组必须先声明再调用
范例
[root@centos8 ~]# name[ceo]=long [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]=long [root@centos8 ~]# name[cto]=wang [root@centos8 ~]# name[coo]=zhang [root@centos8 ~]# echo ${name[coo]} zhang [root@centos8 ~]# echo ${name[ceo]} long [root@centos8 ~]# echo ${name[cto]} wang [root@centos8 ~]# echo ${name[*]} long wang zhang
范例:关联数组
[root@centos8 ~]# declare -A student [root@centos8 ~]# student[name1]=lijun [root@centos8 ~]# student[name2]=ziqing [root@centos8 ~]# student[age1]=18 [root@centos8 ~]# student[age2]=16 [root@centos8 ~]# student[gender1]=m [root@centos8 ~]# student[city1]=nanjing [root@centos8 ~]# student[gender2]=f [root@centos8 ~]# student[city2]=anhui [root@centos8 ~]# student[gender2]=m [root@centos8 ~]# student[name50]=alice [root@centos8 ~]# student[name3]=tom [root@centos8 ~]# for i in {1..50};do echo student[name$i]=${student[name$i]};done
范例:编写脚本,定义一个数组,数组中的元素对应的值是/var/log目录下所有以.log结尾的文件;统计出其下标为偶数的文件中的行数之和
#!/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"
字符串处理
基于偏移量取字符串
#返回字符串变量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} #先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容,注意:- length前空格,并且length必须大于offset ${var: -length:-offset}
范例:
[root@centos8 script40]# str=abcdef我你他 [root@centos8 script40]# echo ${#str} 9 [root@centos8 script40]# echo ${str:2} cdef我你他 [root@centos8 script40]# echo ${str:2:3} cde [root@centos8 script40]# echo ${str:-3} abcdef我你他 [root@centos8 script40]# echo ${str: -3} 我你他 [root@centos8 script40]# echo ${str:2:-3} cdef [root@centos8 script40]# echo ${str: -2:-3} -bash: -3: substring expression < 0 [root@centos8 script40]# echo ${str: -3:-2} 我 [root@centos8 script40]# echo ${str:-3:-2} abcdef我你他 [root@centos8 script40]# echo ${str: -3:-2} 我 [root@centos8 script40]# echo ${str: -5:-2} ef我
基于模式取子串
#其中word可以是指定的任意字符,自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字 符串开头至第一次出现word字符串(含)之间的所有字符,即懒惰模式,以第一个word为界删左留右 ${var#*word} #同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容,即贪婪模 式,以最后一个word为界删左留右 ${var##*word}
范例:
[root@centos8 ~]# file="var/log/messages" [root@centos8 ~]# echo ${file#*/} log/messages [root@centos8 ~]# echo ${file##*/} messages
#其中word可以是指定的任意字符,功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删除字符串最后一个字符向左至第一次出现word字符串(含)之间的所有字符,即懒惰模式,以从右向左的第 一个word为界删右留左 ${var%word*} #同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符,即贪婪模式,以从右向 左的最后一个word为界删右留左 ${var%%word*}
范例:
[root@centos8 ~]# file="var/log/messages" [root@centos8 ~]# echo ${file%/*} var/log [root@centos8 ~]# echo ${file%%/*} var
范例:
[root@centos8 ~]# url=http://www.longxuan.com:8080 [root@centos8 ~]# echo ${url##*:} 8080 [root@centos8 ~]# 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,,}
高级变量
范例:
[root@centos8 ~]# title=ceo [root@centos8 ~]# name=${title-long} [root@centos8 ~]# echo $name ceo [root@centos8 ~]# title= [root@centos8 ~]# name=${title-long} [root@centos8 ~]# echo $name [root@centos8 ~]# unset title [root@centos8 ~]# name=${title-long} [root@centos8 ~]# echo $name long
范例:
[root@centos8 ~]# title=ceo [root@centos8 ~]# name=${title:-long} [root@centos8 ~]# echo $name ceo [root@centos8 ~]# title= [root@centos8 ~]# name=${title:-long} [root@centos8 ~]# echo $name long [root@centos8 ~]# unset title [root@centos8 ~]# name=${title:-long} [root@centos8 ~]# echo $name long
高级变量用法-有类型变量
Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令用于指定变量的类型,两
个命令是等价的
declare [选项] 变量名 选项: -r 声明或显示只读变量 -i 将变量定义为整型数 -a 将变量定义为数组 -A 将变量定义为关联数组 -f 显示已定义的所有函数名及其内容 -F 仅显示已定义的所有函数名 -x 声明或显示环境变量和函数,相当于export -l 声明变量为小写字母 declare -l var=UPPER -u 声明变量为大写字母 declare -u var=lower -n make NAME a reference to the variable named by its value
变量间接引用
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=a [root@centos8 ~]# j=1 [root@centos8 ~]# $i$j=hello -bash: a1=hello: command not found [root@centos8 ~]# eval $i$j=hello [root@centos8 ~]# echo $i$j a1 [root@centos8 ~]# echo $a1 hello
间接变量引用
如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用
variable1的值是variable2,而variable2又是变量名,variable2的值为value,间接变量引用是指通过
variable1获得变量值value的行为
variable1=variable2 variable2=value #示例: i=1 $1=wang
bash Shell提供了两种格式实现间接变量引用
#方法1 #变量赋值 eval tempvar=\$$variable1 #显示值 eval echo \$$variable1 eval echo '$'$variable1 #方法2 #变量赋值 tempvar=${!variable1} #显示值 echo ${!variable1}
范例:
[root@centos8 ~]# ceo=name [root@centos8 ~]# name=long [root@centos8 ~]# echo $ceo name [root@centos8 ~]# echo $$ceo 33722ceo [root@centos8 ~]# echo $$ 33722 [root@centos8 ~]# echo \$$ceo $name [root@centos8 ~]# eval echo \$$ceo long [root@centos8 ~]# eval tmp=\$$ceo [root@centos8 ~]# echo $tmp long [root@centos8 ~]# echo ${!ceo} long
范例:
[root@server ~]# N1=N2 [root@server ~]# N2=longwang [root@server ~]# eval NAME=\$$N1 [root@server ~]# echo $NAME longwang [root@server ~]# NAME=${!N1} [root@server ~]# echo $NAME longwang
范例: 批量创建用户
#!/bin/bash n=$# [ $n -eq 0 ] && { echo "Usage: `basename $0` username..." ; exit 2; } for i in `eval echo {1..$n}`;do user=${!i} id $user &> /dev/null && echo $user is exist || { useradd $user; echo $user is created; } done [root@centos8 ~]# bash create_user.sh hehe xixi haha hehe is created xixi is created haha is created
变量引用 reference
[root@centos8 ~]#cat test.sh #!/bin/bash title=ceo ceo=long #声明引用变量ref declare -n ref=$title [ -R ref ] && echo "reference" # [ -R var ] 是bash4.4新特性 echo ref=$ref ceo=king echo ref=$ref [root@centos8 ~]# bash test.sh reference ref=long ref=king
这篇关于(八)shell编程之数组,字符串还有高级变量的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-09-28AI给的和自己写的Python代码,都无法改变输入框的内容,替换也不行
- 2024-09-27Sentinel配置限流资料:新手入门教程
- 2024-09-27Sentinel配置限流资料详解
- 2024-09-27Sentinel限流资料:新手入门教程
- 2024-09-26Sentinel限流资料入门详解
- 2024-09-26Springboot框架资料:初学者入门教程
- 2024-09-26Springboot框架资料详解:新手入门教程
- 2024-09-26Springboot企业级开发资料:新手入门指南
- 2024-09-26SpringBoot企业级开发资料新手指南
- 2024-09-26Springboot微服务资料入门教程