shell编程之基本数据类型与值操作

Posted givenchy_yzl

tags:

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

基本数据类型与值操作

一、数据类型介绍

什么是数据?为何要有多种类型的数据?
#数据即变量的值,如age=18,18则是我们保存的数据。
#变量的是用来反映/保持事物状态以及状态变化的,毫无疑问针对不同的状态就应该用不同类型的数据去标识

二、基本数据类型

数字

#int整型
定义:age=10
用于标识:年龄,等级,身份证号,qq号,个数

#float浮点型
定义:salary=3.1
用于标识:工资,身高,体重

字符串

#在shell中,加了引号的字符就是字符串类型

定义:name='yzl' 
用于标识:描述性的内容,如姓名,性别,国籍,种族

# 注意1:字符串包含空格必须加引号
[root@web01 ~]# msg="hello yzl"
[root@web01 ~]# msg=hello yzl
-bash: yzl: command not found

# 注意2:连续的字符不加引号包含也是可以的,但我们还是强烈建议加上引号,规范一些
[root@web01 ~]# msg=hello
[root@web01 ~]# echo $msg
hello

# 注意3:单引号与双引号是不同的
" "  	弱引用,引号的特殊字符有意义
' ' 	强引用,引号内所有特殊字符都取消意义
[root@web01 ~]# name=“yzl”
[root@web01 ~]#  echo "${name} is good"
“yzl” is good
[root@web01 ~]# echo '${name} is good'
${name} is good

shell是弱类型语言
[root@web01 ~]# x=10
[root@web01 ~]# y=“3”
[root@web01 ~]# expr $x + $y
13

数组介绍

1、什么是数组?

数组就是一系列元素的集合,一个数组内可以存放多个元素

2、为何要用数组?

我们可以用数组将多个元素汇总到一起,避免单独定义的麻烦

数组分为两种
普通数组:只能使用整数作为数组索引
关联数组:可以使用字符串作为数组索引,需要用declare -A声明

普通数组
=================声明普通数组=================
# 方式一:array=(元素1 元素2 元素3)
array=(egon 18 male)

# 方式二:array=([key1]=value1 [key2]=value2 [key3]=value3)
array=([0]=111 [1]="two" [2]=333)

# 方式三:依次赋值
array_new[0]=111
array_new[1]=222
array_new[2]="third"

# 方式四:利用执行命令的结果设置数组元素:array=($(命令))  或者  array=(`命令`)
该方式会将命令的结果以空格为分隔符切成多个元素然后赋值给数组
[root@aliyun ~]# ls /test
a.txt	b.txt
[root@aliyun ~]# array3=(`ls /test`)
[root@aliyun ~]# declare -a |grep array3
declare -a array3='([0]="a.txt" [1]="b.txt")'


# ps:查看声明过的数组
declare -a

=================访问普通数组=================
[root@egon ~]# ip_array=(1.1.1.1 2.2.2.2 3.3.3.3)

# 正向索引
[root@web01 ~]# ip_array=(1.1.1.1 2.2.2.2 3.3.3.3)
[root@web01 ~]# echo ${ip_array[0]}
1.1.1.1
[root@web01 ~]# echo ${ip_array[1]}
2.2.2.2
[root@web01 ~]# echo ${ip_array[2]}
3.3.3.3

# 负向索引
[root@web01 ~]# echo ${ip_array[-1]}
3.3.3.3
[root@web01 ~]#  echo ${ip_array[-2]}
2.2.2.2
[root@web01 ~]# echo ${ip_array[-3]}
1.1.1.1
结论:
取数组值时,默认只取第一个索引
使用索引可以取值
取索引的最后一个值可以用-1
正向取值从0开始,负向取值从-1开始
如果使用*号索引,取所有值
关联数组
=================声明关联数组=================
#declare -A [变量名] 声明关联数组   -a 声明普通属组
[root@web01 ~]# declare -A list
[root@web01 ~]# list["name"]="yzl"
[root@web01 ~]# list["age"]=18
[root@web01 ~]# list["gender"]="male"
[root@web01 ~]# declare -A |grep list
declare -A list='([gender]="male" [name]="yzl" [age]="18" )'
[root@web01 ~]# echo ${list[*]}
male yzl 18
[root@web01 ~]# echo ${list[name]}
yzl

=================访问关联数组=================
[root@web01 ~]# info=([0]="yzl" ["age"]=18 ["gender"]="male")
[root@web01 ~]#  echo ${info[0]}
yzl
[root@web01 ~]# echo ${info["age"]}
18
[root@web01 ~]# echo ${info["gender"]}
male
结论
使用索引取值
如果使用*号索引,取所有
${yzl[name]}

ps:bash shell只支持一维数组,但数组元素个数没有限制。

三 变量值操作

3.1 获取变量值的长度
[root@localhost ~]# echo ${#url}
15

# 企业面试题:已知变量msg='hello world!',请统计出变量中包含的字符数量
# 方法一:
[root@egon /]# echo ${#msg}
12
# 方法二:
[root@egon /]# echo $msg | wc -L
12
# 方法三:
[root@egon /]# echo $msg|awk '{print length}'
12

# 方法四:
[root@egon ~]# expr length "$msg" #length是一个函数,注意因为msg的值有空格,所以$msg必须用引号包含
12
3.2 切片
${paramter:offset:length}

[root@egon /]# msg="abcdef"
[root@egon /]# echo ${msg:3}  # 从3号索引开始,一直到最后
def
[root@egon /]# echo ${msg:3:2}  # 从3号索引开始,往后数2个字符
de
[root@egon /]# echo ${msg::3}  # 从0开始,往后数3个字符
abc
结论

组成:变量:开始位置:步长
如果开始位置为空,则从0号索引开始
如果步长为空,默认从开始位置切到最后

3.3 截断
# =================》一、砍掉左边的字符《=================
# 1.1 简单使用 
[root@egon ~]# url="www.sina.com.cn"
[root@egon ~]# echo ${url#www.}
sina.com.cn

# 1.2 结合*=》非贪婪,默认情况下*是非贪婪,尽可能地少“吃”字符
[root@egon ~]# echo ${url#*w}
ww.sina.com.cn

# 1.3 结合*=》贪婪,尽可能地多“吃”字符
[root@egon ~]# echo ${url##*w}  # *会尽可能多地吃掉字符,一直匹配到最远的那个w才停下来
.sina.com.cn

# =================》二、砍掉右边的字符《=================
# 1.1 简单使用
[root@egon ~]# url="www.sina.com.cn"
[root@egon ~]# echo ${url%.cn}
www.sina.com

# 1.2 结合*=》非贪婪
[root@egon ~]# echo ${url%.*}
www.sina.com
# 1.3 结合*=》贪婪
[root@egon ~]# echo ${url%%.*}
www

# =================》三、应用示例《=================
[root@egon ~]# hostname
egon.xxx.com
[root@egon ~]# echo $HOSTNAME
egon.xxx.com
[root@egon ~]# echo ${HOSTNAME%.*}
egon.xxx
[root@egon ~]# echo ${HOSTNAME%%.*}
egon
3.4 内容的替换
[root@egon ~]# url="www.sina.com.cn"
[root@egon ~]# echo ${url/sina/baidu}
www.baidu.com.cn
[root@egon ~]# echo ${url/n/N}
www.siNa.com.cn
[root@egon ~]# echo ${url//n/N}  # 贪婪
www.siNa.com.cN

# 应用示例:批量修改文件名称
[root@egon shell]# touch egon_2020_{01..05}_linux.txt
[root@egon shell]# ls
egon_2020_01_linux.txt  egon_2020_02_linux.txt  egon_2020_03_linux.txt  egon_2020_04_linux.txt  egon_2020_05_linux.txt
[root@egon shell]# for i in `ls *linux.txt`;do mv $i ${i/_linux/};done
[root@egon shell]# ls
egon_2020_01.txt  egon_2020_02.txt  egon_2020_03.txt  egon_2020_04.txt  egon_2020_05.txt
3.5 变量的替代
${x:-临时变量信息}
${x:=新的变量信息}
${x:?没有设置变量提示信息}   
${x:+有设置变量提示信息} 


#1、${parameter-word}: 当调取变量没有定义过, 就返回word字符串信息
[root@egon ~]# unset name 
[root@egon ~]# echo ${name}

[root@egon ~]# echo ${name-"egon"}  # 没有定义过变量name,则使用-后的值
egon
[root@egon ~]# 
[root@egon ~]# gender=  # 定义过变量了,则使用变量的原值,哪怕变量的值为空值
[root@egon ~]# echo ${gender-"male"}

[root@egon ~]# 
[root@egon ~]# age=18  
[root@egon ~]# echo ${age-19}  # 定义过变量了,则使用变量的原值
18
[root@egon ~]# 

#2、${parameter:-word}: 当调取变量信息值为空时或未定义变量, 就返回word字符串信息
[root@egon ~]# unset x  
[root@egon ~]# unset y
[root@egon ~]# unset z
[root@egon ~]# 
[root@egon ~]# echo ${x:-aaa}  # 没有定义过变量x,则使用-后的值
aaa
[root@egon ~]# y=
[root@egon ~]# echo ${y:-aaa}  # 定义过变量y,但变量y的值为空值,则使用-后的值
aaa
[root@egon ~]# z=333
[root@egon ~]# echo ${z:-aaa}  # 定义过变量了,并且变量有一个非空的原值,则使用变量的原值
333

#3、{parameter:=word}:当调取变量信息值为空时或未定义,则设置指定字符串为新的变量值
[root@egon /]# unset x
[root@egon /]# echo ${x:=123}
123
[root@egon /]# echo $x
123

#4、${parameter:?word}:当调取变量信息值为空时或未定义,指定为赋值的错误提示信息
[root@egon /]# unset x
[root@egon /]# echo ${x:?该变量没有定义过}
-bash: x: 该变量没有定义过
        
#5、${parameter:+word}:当调取变量信息值为空时或未定义,不做任何处理,否则word字符串将替代变量值
[root@egon /]# unset x
[root@egon /]# echo ${x:+哈哈哈}

[root@egon /]# x=123
[root@egon /]# echo ${x:+哈哈哈}
哈哈哈
结论
1、当变量没有定义的时候,给一个临时默认值: echo ${school:-"xxx"}
2、当变量没有定义的时候,给变量赋予一个值:echo ${school:="xxx"}
3、当变量没有定义的时候,给变量错误提示信息:echo ${school:?"这个变量不存在"}
4、当变量存在时,给变量一个对外一个提示信息:echo ${school:+"这个变量已存在"}
3.6 let
# (1) 变量的值
[root@egon ~]# j=1
[root@egon ~]# let ++j
[root@egon ~]# echo $j
2
[root@egon ~]# 

# (2) 表达式的值
[root@egon ~]# unset i
[root@egon ~]# unset j
[root@egon ~]# 
[root@egon ~]# i=1
[root@egon ~]# j=1
[root@egon ~]# 
[root@egon ~]# let x=i++  # 先把i赋值给x,然后再++
[root@egon ~]# let y=++j  # 先++j,然后再把j的结果赋值给y
[root@egon ~]# echo $i
2
[root@egon ~]# echo $j
3
[root@egon ~]# echo $x
1
[root@egon ~]# echo $y
2
结论
x++(先赋值,后加减) 和 ++x(先加减,后赋值)
3.7 取命令的结果赋值给变量:
# ``与$()
` `  命令替换 等价于 $()   反引号中的shell命令会被先执行
[root@localhost ~]# touch `date +%F`_file1.txt  
[root@localhost ~]# touch $(date +%F)_file2.txt 

[root@localhost ~]# disk_free3="df -Ph |grep '/$' |awk '{print $4}'"  # 错误
[root@localhost ~]# disk_free4=$(df -Ph |grep '/$' |awk '{print $4}') # 正确
[root@localhost ~]# disk_free5=`df -Ph |grep '/$' |awk '{print $4}'`  # 正确

以上是关于shell编程之基本数据类型与值操作的主要内容,如果未能解决你的问题,请参考以下文章

linux12shell编程 -->变量值操作

shell 基本数据类型

shell编程 之 test命令

lua学习之类型与值篇

linux之shell编程

linux之shell编程基本语法