一 数据类型介绍
一、什么是数据?为什么要有多种类型的数据?
1、数据即变量的值,如age=18,18则是我们保存的数据。
2、变量的是用来反映/保持状态以及状态变化的,毫无疑问针对不同的状态就应该用不同类型的数据去标识
二、shell是一门解释型、弱类型、动态语言
概括地说,编程语言的划分方式有以下三种
1、编译型or解释型
编译型:
在编译型语言写的程序执行之前,需要一个专门的编译过程,把源代码编译成机器语言的文件,如exe格式的文件,以后要再运行时,直接使用编译结果即可,如直接运行exe文件。因为只需编译一次,以后运行时不需要编译,所以编译型语言执行效率高。
总结:
1.一次性的编译成平台相关的机器语言文件,运行时脱离开发环境,运行效率高;
2.与特定平台相关,一般无法移植到其他平台;
3.现有的C、C++、Objective、go等都属于编译型语言。
解释型:
使用专门的解释器对源程序逐行解释成特定平台的机器码并立即执行。是代码在执行时才被解释器一行行动态翻译和执行,而不是在执行之前就完成翻译。
总结:
1.解释型语言每次运行都需要将源代码解释称机器码并执行,效率较低;
2.只要平台提供相应的解释器,就可以运行源代码,所以可以方便源程序移植;
3.Python等属于解释型语言。
2、强类型or弱类型
强类型语言:
数据类型不可以被忽略的语言
即变量的数据类型一旦被定义,那就不会再改变,除非进行强转。
在python中,例如:name = 'egon',这个变量name在被赋值的那一刻,数据类型就被确定死了,是字符型,值为'egon'。
弱类型语言:
数据类型可以被忽略的语言
比如linux中的shell中定义一个变量,是随着调用方式的不同,数据类型可随意切换的那种,即shell对数据类型的概念没有那么强的要求
3、动态型or静态型
动态语言 :
运行时才进行数据类型检查
即在变量赋值时,就确定了变量的数据类型,不用事先给变量指定数据类型
静态语言:
需要事先给变量进行数据类型定义
所以综上所述,shell是一门解释型的弱类型动态语言
二 基本的数据类型
一、数字
int 整型
定义:age=10
用于标识:年龄,等级,身份证号,qq号,个数
float 浮点型
定义:salary=3.1
用于标识:工资,身高,体重
二、str 字符串
在shell中,加了引号的字符就是字符串类型
定义:name='"xiaowu'
用于标识:描述性的内容,如姓名,性别,国籍,种族
# 注意1:字符串包含空格必须加引号
[root@xiaowu ~]# name="xiao wu"
[root@xiaowu ~]# name=xiao wu
-bash: wu: command not found
# 注意2:连续的字符不加引号包含也是可以的,但我们还是强烈建议加上引号,规范一些
[root@xiaowu ~]# name=xiaowu
[root@xiaowu ~]# echo $name
xiaowu
# 注意3:单引号与双引号是不同的
" " 弱引用,引号的特殊字符有意义
' ' 强引用,引号内所有特殊字符都取消意义
[root@xiaowu ~]# name="xiaowu"
[root@xiaowu ~]# echo $name is good
xiaowu is good
[root@xiaowu ~]# echo "$name" is good
xiaowu is good
[root@xiaowu ~]# echo '$name' is good
$name is good
ps: shell是弱类型语言
[root@xiaowu ~]# x=3
[root@xiaowu ~]# y="8"
[root@xiaowu ~]# expr $x + $y
11
三、数组
介绍
1、什么是数组?
数组就是一系列元素的集合,一个数组内可以存放多个元素
2、为什么要用数组?
我们可以用数组将多个元素汇总到一起,避免单独定义的麻烦
数组的分类
普通数组:只能以整数作为数组索引
关联数组:可以使用字符串作为数组索引,需要用declare -A声明
1、普通数组
=================普通数组的定义=================
# 方式一:array=(元素1 元素2 元素3)
array=(xiaowu 18 male)
# 方式二:array=([key1]=value1 [key2]=value2 [key3]=value3)
array1=([0]=111 [1]="abc" [2]="zbc")
# 方式三:依次赋值
[root@xiaowu ~]# array2_new[0]="one"
[root@xiaowu ~]# array2_new[1]=222
[root@xiaowu ~]# array2_new[2]=333
# 方式四:利用执行命令的结果设置数组元素:array=($(命令)) 或者 array=(`命令`)
该方式会将命令的结果以空格为分隔符切成多个元素然后赋值给数组
[root@xiaowu ~]# ll
total 36
-rw-r--r-- 1 root root 303 Jan 11 12:00 aa.sh
-rw-r--r-- 1 root root 385 Jan 11 20:53 a.sh
-rw-r--r-- 1 root root 557 Jan 12 11:55 b.sh
-rw-r--r-- 1 root root 357 Jan 11 20:59 firsh.sh
-rw-r--r-- 1 root root 57 Jan 11 11:11 hello.sh
-rw-r--r-- 1 root root 1102 Jan 12 10:49 ip_hostname.sh
-rw-r--r-- 1 root root 421 Jan 12 11:43 ping_host.sh
-rw-r--r-- 1 root root 335 Jan 12 11:46 ping.sh
-rw-r--r-- 1 root root 333 Jan 12 15:26 while.sh
array3=(`ls`)
# ps:查看声明过的数组
declare -a
declare -a array='([0]="xiaowu" [1]="18" [2]="male")'
declare -a array1='([0]="111" [1]="abc" [2]="zbc")'
declare -a array2_new='([0]="one" [1]="222" [2]="333")'
declare -a array3='([0]="aa.sh" [1]="a.sh" [2]="b.sh" [3]="firsh.sh" [4]="hello.sh" [5]="ip_hostname.sh" [6]="ping_host.sh" [7]="ping.sh" [8]="while.sh")'
===============访问普通数组==============
定义一个数组
array=(xiaowu 18 male)
1、访问数组内指定位置的元素
正向索引
[root@xiaowu ~]# echo ${array[0]}
xiaowu
[root@xiaowu ~]# echo ${array[1]}
18
[root@xiaowu ~]# echo ${array[2]}
male
负向索引
[root@xiaowu ~]# echo ${array[-1]}
male
2、访问数组内全部元素信息
[root@xiaowu ~]# echo ${array[*]}
xiaowu 18 male
[root@xiaowu ~]# echo ${array[@]}
xiaowu 18 male
3、获取数组元素的个数
[root@xiaowu ~]# echo ${#array[*]}
3
[root@xiaowu ~]# echo ${#array[@]}
3
=================添加、修改数组元素==============
定义一个数组
[root@xiaowu ~]# array=(xiaowu 18 male)
修改数组某个元素
[root@xiaowu ~]# echo ${array[0]}
xiaowu
[root@xiaowu ~]# array[0]="XIAOWU" #修改
[root@xiaowu ~]# echo ${array[0]}
XIAOWU
添加元素在数组
[root@xiaowu ~]# declare -a | grep array=
declare -a array='([0]="XIAOWU" [1]="18" [2]="male")'
[root@xiaowu ~]# array[3]="IT" #添加
[root@xiaowu ~]# declare -a | grep array=
declare -a array='([0]="XIAOWU" [1]="18" [2]="male" [3]="IT")'
================删除数组及数组元素===========
[root@xiaowu ~]# unset array[0] #删除某个元素
[root@xiaowu ~]# echo ${array[*]}
18 male IT
[root@xiaowu ~]# declare -a | grep array=
declare -a array='([1]="18" [2]="male" [3]="IT")'
[root@xiaowu ~]# unset array[2] #删除某个元素
[root@xiaowu ~]# echo ${array[*]}
18 IT
[root@xiaowu ~]# declare -a | grep array=
declare -a array='([1]="18" [3]="IT")'
[root@xiaowu ~]# declare -a | grep array
declare -a array='([1]="18" [3]="IT")'
declare -a array1='([0]="111" [1]="abc" [2]="zbc")'
declare -a array2_new='([0]="one" [1]="222" [2]="333")'
declare -a array3='([0]="aa.sh" [1]="a.sh" [2]="b.sh" [3]="firsh.sh" [4]="hello.sh" [5]="ip_hostname.sh" [6]="ping_host.sh" [7]="ping.sh" [8]="while.sh")'
[root@xiaowu ~]# unset array #删除一个组
[root@xiaowu ~]# declare -a | grep array
declare -a array1='([0]="111" [1]="abc" [2]="zbc")'
declare -a array2_new='([0]="one" [1]="222" [2]="333")'
declare -a array3='([0]="aa.sh" [1]="a.sh" [2]="b.sh" [3]="firsh.sh" [4]="hello.sh" [5]="ip_hostname.sh" [6]="ping_host.sh" [7]="ping.sh" [8]="while.sh")'
[root@xiaowu ~]# unset array1 #删除一个组
[root@xiaowu ~]# unset array3 #删除一个组
[root@xiaowu ~]# declare -a | grep array
declare -a array2_new='([0]="one" [1]="222" [2]="333")'
============数组内元素的截取==============
[root@xiaowu ~]# array=(xiaowu 18 male IT 1.80)
[root@xiaowu ~]# declare -a | grep array
declare -a array='([0]="xiaowu" [1]="18" [2]="male" [3]="IT" [4]="1.80")'
[root@xiaowu ~]# echo ${array[*]:1} #截取索引1开始一直到最后的元素
18 male IT 1.80
[root@xiaowu ~]# echo ${array[*]:1:3} #截取索引1到3的元素
18 male IT
[root@xiaowu ~]# echo ${array[*]#18} #截取除元素18以外的元素
xiaowu male IT 1.80
[root@xiaowu ~]# echo ${array[*]#male} #截取除元素male以外的元素
xiaowu 18 IT 1.80
===========数组内容的替换==========
[root@xiaowu ~]# echo ${array[*]}
xiaowu 18 male IT 1.80
[root@xiaowu ~]# echo ${array[*]/18/21} #将元素18替换成21
xiaowu 21 male IT 1.80
[root@xiaowu ~]# echo ${array[*]/xiaowu/XIAOWU} #将元素xiaowu替换成XIAOWU
XIAOWU 18 male IT 1.80
2、关联数组
=========关联数组的定义=========
方式一
[root@xiaowu ~]# declare -A info #定义关联数组名
[root@xiaowu ~]# info=([name]="xiaowu" ["age"]=18 ["gender"]="male") #定义关联数组的索引和元素
[root@xiaowu ~]# declare -A |grep info
declare -A info='([gender]="male" [name]="xiaowu" [age]="18" )'
方式二
[root@xiaowu ~]# unset info #删除方式一定义的关联数组
[root@xiaowu ~]# declare -A info=([name]="xiaowu" ["age"]=18 ["gender"]="male") #定义关联数组
[root@xiaowu ~]# declare -A |grep info
declare -A info='([gender]="male" [name]="xiaowu" [age]="18" )'
三 变量值操作
一、获取变量值的长度
[root@xiaowu ~]# url="www.baidu.com"
[root@xiaowu ~]# echo $url
www.baidu.com
方式一:
[root@xiaowu ~]# echo ${#url}
13
方式二
[root@xiaowu ~]# echo $url | wc -L
13
方式三
[root@xiaowu ~]# echo $url | awk '{print length}'
13
方式四
[root@xiaowu ~]# expr length "$url"
13
###length是一个函数,注意如果url的值有空格,$url必须用引号包含
二、切片
[root@xiaowu ~]# msg="abcdefg"
0123456
###打印从第三个字符开始,一直到最后
[root@xiaowu ~]# echo ${msg:3}
defg
##从第三个字符开始,打印两个字符
[root@xiaowu ~]# echo ${msg:3:2}
de
##从头开始(0),打印三个字符
[root@xiaowu ~]# echo ${msg::3}
abc
三、截断
1、从左开始匹配
[root@xiaowu ~]# url="www.baidu.com.cn"
##截断"www.",打印剩下的内容
[root@xiaowu ~]# echo ${url#www.}
baidu.com.cn
##截断"w"非贪婪匹配,打印剩下的内容
[root@xiaowu ~]# echo ${url#*w}
ww.baidu.com.cn
##截断"w"贪婪匹配,打印剩下的内容
[root@xiaowu ~]# echo ${url##*w}
.baidu.com.cn
2、从右边开始匹配
[root@xiaowu ~]# url="www.baidu.com.cn"
##从右往左开始截断".cn",打印剩下的内容
[root@xiaowu ~]# echo ${url%.cn}
www.baidu.com
##从右往左开始截断".*"(非贪婪),打印剩下的内容
[root@xiaowu ~]# echo ${url%.*}
www.baidu.com
##从右往左开始截断".*"(贪婪),打印剩下的内容
[root@xiaowu ~]# echo ${url%%.*}
www
四、内容的替换
[root@xiaowu ~]# url="www.nnn.com.cn"
###将"n"替换成"N"
[root@xiaowu ~]# echo ${url/n/N}
www.Nnn.com.cn
###将"n"替换成"N"(贪婪匹配)
[root@xiaowu ~]# echo ${url//n/N}
www.NNN.com.cN
五、变量的替代
${x:-临时变量信息}
${x:=新的变量信息}
${x:?没有设置变量提示信息}
${x:+有设置变量提示信息}
#1、${parameter-word}: 当调取变量没有定义过, 就返回字符串信息
##没有定义过name,则使用-后的值
[root@xiaowu ~]# unset name
[root@xiaowu ~]# echo $name
[root@xiaowu ~]# echo ${name-"xiaowu"}
xiaowu
## 定义过变量了,则使用变量的原值,哪怕变量的值为空值
[root@xiaowu ~]# name=""
[root@xiaowu ~]# echo ${name-"xiaowu"}
##定义过变量了,则使用变量的原值
[root@xiaowu ~]# name="xiaowu"
[root@xiaowu ~]# echo ${name-"XIAO"}
xiaowu
#2、${parameter:-word}: 当调取变量信息值为空时或未定义变量, 就返回word字符串信息
#### 没有定义过变量x,则使用-后的值
[root@xiaowu ~]# unset name
[root@xiaowu ~]# echo ${name:-"xiaowu"}
xiaowu
###定义过变量y,但变量y的值为空值,则使用-后的值
[root@xiaowu ~]# name=""
[root@xiaowu ~]# echo ${name:-"xiaowu"}
xiaowu
### 定义过变量了,并且变量有一个非空的原值,则使用变量的原值
[root@xiaowu ~]# name="XIAO"
[root@xiaowu ~]# echo ${name:-"xiaowu"}
XIAO
#3、{parameter:=word}:当调取变量信息值为空时或未定义,则设置指定字符串为新的变量值
[root@xiaowu ~]# unset name
[root@xiaowu ~]# echo ${name:=xiaowu}
xiaowu
[root@xiaowu ~]# echo $name
xiaowu
#4、${parameter:?word}:当调取变量信息值为空时或未定义,指定为赋值的错误提示信息
[root@xiaowu ~]# unset name
[root@xiaowu ~]# echo ${name:?该变量不存在}
-bash: name: 该变量不存在
[root@xiaowu ~]# echo $?
1
#5、${parameter:+word}:当调取变量信息值为空时或未定义,不做任何处理,否则word字符串将替代变量值
[root@xiaowu ~]# unset name
[root@xiaowu ~]# echo ${name:+存在这个变量}
[root@xiaowu ~]# name="xiaowu"
[root@xiaowu ~]# echo ${name:+存在这个变量}
存在这个变量
六、变量的数值计算
1、(())----->双括号计算,支持整数计算
[root@xiaowu ~]# echo $((1+2))
3
[root@xiaowu ~]# ((a=3*5))
[root@xiaowu ~]# echo $a
15
[root@xiaowu ~]# echo $((2*7-6/3+5))
17
2、i++、i--、++i、--i,支持整数计算
i++、i--、++i、--i的区别
1、单独拿出来说,++i和i++意思都是一样的,都是i=i+1。
2、如果当做运算符来说,就是a=i++或者a=++i这样的形式。情况就不一样了。
先说a=i++,这个运算的意思是先把i的值赋予a,然后在执行i=i+1;先赋值,后运算
而a=++i,这个的意思是先执行i=i+1,然后在把i的值赋予a;先计算,后赋值。
举个例子来说,如果一开始i=4。
那么执行a=i++这条语句之后,a=4,i=5;
那么执行a=++i这条语句之后,i=5,a=5;
同理,i--和--i的用法也是一样的。
i++
[root@xiaowu ~]# a=1
[root@xiaowu ~]# echo $((a++))
1
[root@xiaowu ~]# echo $a
2
[root@xiaowu ~]#
i--
[root@xiaowu ~]# b=6
[root@xiaowu ~]# echo $((b--))
6
[root@xiaowu ~]# echo $b
5
[root@xiaowu ~]#
++i
[root@xiaowu ~]# echo $b
4
[root@xiaowu ~]# echo $((++b))
5
[root@xiaowu ~]# echo $b
5
[root@xiaowu ~]#
--i
[root@xiaowu ~]# echo $b
5
[root@xiaowu ~]# echo $((--b))
4
[root@xiaowu ~]# echo $b
4
[root@xiaowu ~]#
3、let、expor、$[ ],支持整数计算
let
[root@xiaowu ~]# let i=1+1
[root@xiaowu ~]# echo $i
2
[root@xiaowu ~]# let i=1+i
[root@xiaowu ~]# echo $i
3
expr
[root@xiaowu ~]# expr 3 + 1
4
[root@xiaowu ~]# expr 3 - 1
2
[root@xiaowu ~]# expr 3 * 2
6
[root@xiaowu ~]# expr 8 / 2
4
$[ ]
[root@xiaowu ~]# echo $[1+3]
4
[root@xiaowu ~]# echo $[2*3]
6
[root@xiaowu ~]# echo $i
3
[root@xiaowu ~]# echo $[i+3]
6
[root@xiaowu ~]# echo $[i*3]
9
4、 bc、awk,支持小数计算
bc
[root@xiaowu ~]# echo 1+1.3|bc
2.3
[root@xiaowu ~]# echo 15/2|bc
7
[root@xiaowu ~]# echo 2.3*2|bc
4.6
[root@xiaowu ~]# echo 2.3-1.1|bc
1.2
awk
[root@xiaowu ~]# echo "15 2"|awk '{print ($1+$2)}'
17
[root@xiaowu ~]# echo "15 2"|awk '{print ($1*$2)}'
30
[root@xiaowu ~]# echo "15 2"|awk '{print ($1-$2)}'
13
[root@xiaowu ~]# echo "15 2"|awk '{print ($1/$2)}'
7.5
七、`` 、$()
` ` 命令等价于 $() 反引号中的shell命令会被先执行
[root@xiaowu ~]# touch `date +%F`_file1.txt
[root@xiaowu ~]# ll
total 0
-rw-r--r-- 1 root root 0 Jan 18 12:04 2021-01-18_file1.txt
[root@xiaowu ~]# touch $(date +%F)_file2.txt
[root@xiaowu ~]# ll
total 0
-rw-r--r-- 1 root root 0 Jan 18 12:04 2021-01-18_file1.txt
-rw-r--r-- 1 root root 0 Jan 18 12:05 2021-01-18_file2.txt