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

时间: 2024-08-24 22:49:41

shell编程进阶之数组的相关文章

shell编程进阶

Shell编程进阶 Shell结构以及执行 [[email protected] ~]# mkdir shell [[email protected] ~]# cd shell/ [[email protected] shell]# vim first.sh #!/bin/bash ##The first test shell script ##written by wangchao ls /tmp/ echo "This is the first script." [[email p

Shell编程进阶篇(完结)

1.1 for循环语句 在计算机科学中,for循环(英语:for loop)是一种编程语言的迭代陈述,能够让程式码反复的执行. 它跟其他的循环,如while循环,最大的不同,是它拥有一个循环计数器,或是循环变数.这使得for循环能够知道在迭代过程中的执行顺序. 1.1.1 shell中的for循环 shell中的for 循环与在c中不同,它包含三种形式:第一种结构是列表for 循环;第二种结构就是不带列表的for循环:第三种就类似于C语言. ①   列表for循环(常用) #!/bin/bash

Shell编程进阶 2.2 shell数组

给一个字符指定一个数组 怎么显示数组 a=1 echo $a 1 a=(1 2 3 4) echo $a 1 echo ${a[@]} 1 2 3 4 echo ${a[*]} 1 2 3 4 指定显示数组中第几个数字 echo ${a[0]} 1 echo ${a[2]} 3 echo ${a[3]} 4 echo ${a[4]} 空格 增加数组 a[4]=9 echo ${a[4]} 9echo ${a[*]}1 2 3 4 9 更改数组中的某个元素 a[2]=7 echo ${a[*]}

shell编程函数与数组

1.shell中函数 (1)shell中函数的语法 语法一: 函数名(){ 指令 return n } 语法二: function 函数名(){ 指令 return n } (2)shell中函数的调用执行 1)直接执行函数名即可,在执行函数时,不要带小括号,函数定义及函数体必须要在执行的函数名前定义. 2)带参数的函数的执行方法:函数名  参数1  参数2 (3)函数带参数的说明 1)在函数体重,位置函数都可以是函数的参数 2)父脚本的参数在函数中则临时地被函数参数所掩盖或隐藏 3)$0比较特

linux shell编程进阶学习

第一节:基础 ls -lh  --可以用户友好的方式看到文件大小 file 文件名 --查看文件类型 stat 文件名 --查看文件当前状态 man 命令/函数名 --查看详细的帮助文档 man中看某一命令选项的定位技巧  -- 输入/ -n -n前面要有一定的空格 #!/bin/bash echo "Hello World!" chmod 777 hello.sh或chmod a+x hello.sh等 ./hello.sh执行 echo -e选项用来增强,支持转义字符. var=w

Shell 编程进阶

Shell 介绍 date 命令 自定义变量 if 逻辑判断 case 选择 for 循环 while 循环 Shell 中断继续退出 Shell 函数 Shell 数组

shell编程进阶篇

上一篇文章介绍的是shell的基础知识:https://blog.51cto.com/14048416/2355550??有人会说,shell简单啊,就是一些命令的堆砌啊,是的一些简单的操作仅仅执行几个命令就行了,但是相对一些复杂的业务和要求下,如果只能做到命令的堆砌,那也太有损shell的名声了.??小编通过一个例子给大家介绍,如果没有逻辑和条件,只是命令的堆砌,那么对维护Linux,是多么大的灾难. #需求:清除/var/log 下message 日志文件命令堆砌 #!/bin/bash #

shell脚本进阶之数组基础

SHELL脚本--shell数组基础 ? 数组和变量的区别:变量在内存中占用的空间是离散的,数组在内粗中开辟一段连续的大内存空间,随后数组中的每个元素都放入数组内存中.数组元素使用index标识. ? bash里有两种数组普通数组和关联数组.普通数组只能使用整数类形数值作为数组索引,关联数组可以使用字符串作为索引.关联数组的另外三种称呼:字典(dict),hash结构和映射(map),是一种key和value一一对应的关系. 一.普通数组 1.1定义普通数组 方法一: [[email prote

Shell编程进阶 2.0 shell中断继续退出

break    continue   exit break 结束本次for循环 写个for循环脚本 vim for2.sh #!/bin/bash ## for i in `seq 1 5` do echo $i if [ $i -eq 4 ] then break fi echo $i done echo "for done" sh for2.sh 1122334for done continue 结束本次循环 #!/bin/bash ## for i in `seq 1 5` d