shell编程进阶之数组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell编程进阶之数组相关的知识,希望对你有一定的参考价值。

数组ARRAY

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

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

 

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

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

declare [OPTION] 变量名

-r  声明或显示只读变量

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

-a  声明或显示索引数组

-A  声明或显示关联数组

-f  显示系统的所有函数

-F  仅显示所有函数名

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

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

-u  声明变量为大写字母 declare –u 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,3,5,7,9,格式为起始值,增量值,结束值

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

 

echo {1..10..2}  //显示1,3,5,7,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

本文出自 “rackie” 博客,请务必保留此出处http://rackie386.blog.51cto.com/11279229/1945757

以上是关于shell编程进阶之数组的主要内容,如果未能解决你的问题,请参考以下文章

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

Shell 编程进阶

shell编程进阶

shell编程之数组

Linux-Shell脚本编程进阶

linux之Shell编程--Shell数组实例演示