【Linux】 shell 常用的数据类型(数字、字符串和数组)和运算、比较

本文介绍了Shell中数字(包括整数和浮点数)的计算,如使用expr、$((运算式))和$[运算式],以及浮点数通过bc库进行运算。同时,详细讲解了字符串的相等性和长度获取,以及数组的操作,包括获取长度和遍历元素。文章强调了在进行相等性判断和比较大小时的注意事项,如使用-eq关系运算符和双等号==的适用场景。
摘要由CSDN通过智能技术生成

概述

Shell的常用的数据类型主要有以下三种,分别为数字、字符串和数组。

数字和字符串在进行比较时的注意事项:

  • == 可以用于数字,也可以用于字符串,但是建议在数字时禁用,改用-eq语法
  • >、>= 等比较符号可以用于数字的比较,但是建议禁用,改用-eq语法
  • 字符串中一般不会使用 >、>= 等比较符号,如果强行使用,表示按照字典顺序比较 ASCII码, 因为 > 本身是重定向的符号,因而在shell编程中需要加\来转义

注意:shell没有boolean 类型, f=true ,都要当做字符串来看待,比较时用类似 if [[ f == “true" ]] 语法进行比较

1. 数字

数字主要分为整数(int)和浮点数(float)

age=10    		 #定义一个整数10的变量名为age
echo ${age}  	#显示该变量的值,输出结果为:10

height=190.2   		#定义一个浮点数190.2的变量名为height
echo ${height}   #显示该变量的值,输出结果为:190.2

在这里插入图片描述

1.1 计算

如果我们想计算两个整数和两个浮点数相加在shell中应该是什么样。

1.1.1 整数计算

在shell中所有变量默认都是字符串型,不能直接运算的,如果想直接运算需要用expr算数运算符、“$((运算式))” 双括号形式 、“$[运算式]”这种形式

反例:


A=10    		 #定义一个变量A的值是10
B=5    			 #定义一个变量B的值是5
echo "$A+$B"     #先按着正常的思路来看下打印值是什么
#  打印的结果为 “10+5”  ,说明echo后的运算被当做字符串进行处理了
1.1.1.1 $((运算式))语法

正例:


A=10;B=5;echo "$(($A+$B))"       
#这样处理打印的结果就为 15 了
1.1.1.2 $[运算式]语法
A=10;B=5;echo $[$A+$B]   
#这样处理打印的结果就为 15 了
1.1.1.3 expr 算数运算符

算数运算符就是我们最常见的,常用的主要有+(加)、-(减)、*(乘)、/(除)、%(取余)、=(赋值)、==(等于)、!=(不等于)。

下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:

运算符说明举例
+加法`expr $a + $b` 结果为 30。
-减法`expr $a - $b` 结果为 -10。
*乘法`expr $a \* $b` 结果为  200。
/除法`expr $b / $a` 结果为 2。
%取余`expr $b % $a` 结果为 0。
=赋值a=$b 将把变量 b 的值赋给 a。
==相等。用于比较两个数字,相同则返回 true。[ $a == $b ] 返回 false。
!=不相等。用于比较两个数字,不相同则返回 true。[ $a != $b ] 返回 true。

注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。

加减乘除运算

shell是不支持简单的数学运算的,这时候我们就可以使用expr命令来实现shell中的简单运算,expr 是一款表达式计算工具,使用它能完成表达式的求值操作。expr的命令使用方法是:比如1+2要写成expr 1 + 2,expr和计算公式需要写在 ` ` 中(方括号,esc下面的那个按钮)并且数值和运算符之间要有空格 `expr 1+2`是不对的。

不带运算符,会当做普通字符串进行输出:

echo "1+2"   #先试下正常的运算方式能否得到结果
#打印结果  1+2

带了运算符,如果没有空格,会当做普通字符串进行输出

echo `expr 1+2`   #数值和运算符中间没有空格时
#打印结果  1+2

正例,注意乘法运算需要转义字符

echo `expr 1 + 2`   #加法
#打印结果  3
echo `expr 2 - 1`   #减法
#打印结果  1
echo `expr 2 \* 3`   #乘法必须要使用反斜杠才能实现
#打印结果  6
echo `expr 2 * 3`   #乘法没有反斜杠时
#打印结果  expr: 语法错误
 
echo `expr 6 / 2`   #除法
#打印结果  3
echo `expr 6 % 4`   #取余
#打印结果  2

1.1.2 浮点数计算

Shell默认不支持浮点数运算,需要通过第三方库bc进行浮点运算,安装方式为:yum -y install bc

C=3.3    #给变量C赋值浮点数3.3
D=3.4    #给变量D赋值浮点数3.4
echo "$C+$D"    #看下浮点数能不能正常显示出来
#浮点数可以正常显示出来 3.3+3.4
echo $[$C+$D]    #再用下计算整数的方法去计算浮点数试试
#但是计算时就会报错了  -bash: 3.3+3.4: syntax error: invalid arithmetic operator (error token is ".3+3.4")
echo "$C+$D" | bc    #计算浮点数就需要安装第三方库bc来进行计算了
#安装bc后进行计算可以正常计算出来  6.7    bc安装方式:yum -y install bc

在这里插入图片描述

1.2 相等性或不等判断

1.2.1 []、[[]] 语法中使用==、!=进行相等性判断

进行相等性判断时,使用== 或=均可以,但是建议使用==,避免使用=,因为后者用在表达式中,有的表示赋值,尽量避免混淆,语法如下:
在这里插入图片描述

注意:if 条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。

在 if 语法中,放在[] 中 ,示例:

#!/bin/bash
a=10
b=20

if [ $a == $b ]
then
   echo "a 等于 b"       # 不打印
fi
if [ $a != $b ]
then
   echo "a 不等于 b"     #打印
fi

1.2.2 []、[[]] 语法中使用 -eq关系运算符

下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20,注意使用中括号或双中括号语法:

运算符说明举例
-eq检测两个数是否相等,相等返回 true。[ $a -eq $b ] 返回 false。
-ne检测两个数是否不相等,不相等返回 true。[ $a -ne $b ] 返回 true。
-gt检测左边的数是否大于右边的,如果是,则返回 true。[ $a -gt $b ] 返回 false。
-lt检测左边的数是否小于右边的,如果是,则返回 true。[ $a -lt $b ] 返回 true。
-ge检测左边的数是否大于等于右边的,如果是,则返回 true。[ $a -ge $b ] 返回 false。
-le检测左边的数是否小于等于右边的,如果是,则返回 true。[ $a -le $b ] 返回 true。

示例:

#!/bin/bash

a=10
b=20

if [ $a -eq $b ]
then
   echo "$a -eq $b : a 等于 b"
else
   echo "$a -eq $b: a 不等于 b"    # 打印
fi

if [ $a -ne $b ]
then
   echo "$a -ne $b: a 不等于 b"   # 打印
else
   echo "$a -ne $b : a 等于 b"
fi

if [ $a -gt $b ]
then
   echo "$a -gt $b: a 大于 b"
else
   echo "$a -gt $b: a 不大于 b"    # 打印
fi

if [ $a -lt $b ]
then
   echo "$a -lt $b: a 小于 b"      # 打印
else
   echo "$a -lt $b: a 不小于 b"
fi

if [ $a -ge $b ]
then
   echo "$a -ge $b: a 大于或等于 b"
else
   echo "$a -ge $b: a 小于 b"    # 打印
fi

if [ $a -le $b ]
then
   echo "$a -le $b: a 小于或等于 b"   # 打印
else
   echo "$a -le $b: a 大于 b"
fi

关系运算符的应用范围只支持数字(确切的说是整数,小数暂不确定),不支持字符串,因此 建议数字 进行关系运算时采用这种方案,这样如果数字类型变量误定义为字符串类型,可以及时发现错误,例如:

[root]$ a=10;b=5a;[ $a -eq $b ]   
bash: [: 5a: integer expression expected  # 由于b变量是字符串,执行时报类型不是整型错误

1.3 比较大小

1.3.1 在if [] 或 if[[]] 语句中使用 数学符号> 、<、>=、<=

  • 当目标是数字类型时,都支持>、>=等 数字比较符,但是都 不建议使用,建议使用 -eq语法

  • 但是要注意的是 [] 需要增加转义字符,原因是[]默认 不识别特殊字符,而[[]] 天生支持

    a=10;b=20; [ $a < $b ] ;echo $?        //单中括号执行报错,不识别 <a=10;b=20; [[ $a < $b ]];echo $?	 //双中括号执行成功	,打印0
    a=10;b=20;  [ $a \< $b ] ;echo $?   //转义字符执行成功,打印0
    a=10;b=20aabc; [[ $a < $b ]];echo $?  //不会报错,当目标误传为字符串时,不容易发现错误,因此不建议使用 <这种语法,建议使用 -eq语法
    

1.3.2 在if [] 或 if[[]] 语句中使用-gt 等语法

参见 < 1.2.2 []、[[]] 语法中使用 -eq关系运算符>章节

1.3.3 使用$(())语法

< 小于(需要双括号),如:  if (("$a" < "$b"))
<= 小于等于(需要双括号),如: if (("$a" <= "$b"))
> 大于(需要双括号),如: if (("$a" > "$b"))
>= 大于等于(需要双括号),如: if (("$a" >= "$b"))

在 if 语法中,放在 (( )) 中 ,要和 中括号区分开来,示例:

a=10
b=20

if(("$a" < "$b"))
then
   echo "a 小于 b"       # 不打印
fi

  • 双括号结构中,变量名引用可以加 $,也可以不加;
  • 运算符前后可以有空格,也可以没有
  • 但是为了方便识别,建议加 $ 并且保留空格

1.4

=、==、-eq的区别
(1)单等号和双等号都能用于字符string类型和整型integer的相等判断。
(2)相等关系运算符“-eq”仅能用于整型integer的相等比较。用于test 或 [] 或 [[]]
(3)相等关系运算符“-eq”不能在算数运算表达式“(( ))”中
(4)在 if 条件表达式 “[ ]”中,单等号和双等号等价,都是相等算数运算符。
(5)在算数运算表达式“(( ))”中,单等号是赋值算数运算符,双等号为相等算数运算符。

总结:在进行相等判断时,最通用的方法是使用双等号“==”相等判断符,避免使用单引号引起歧义。而且数字比较和字符串比较都可以用 == 号,并且建议数字类型时使用 -eq 语法,这样可以检测非数字异常。

2、字符串

字符串在shell中可以使用单引号、双引号、不带引号都行,但是建议最好根据实际情况去选用单引号或者双引号,不要不带引号,有时候变量中如果有空格是很容易出错的。

更多参见 【Linux】Shell(Bash)单引号、双引号、不加引号和反引号用法和区别详解

不带引号的情况:

Atom=apeople   #定义变量Atom,变量值中没有空格
echo ${Atom}   #显示该变量的值
#变量的值为apeople
Atom1=a people #定义变量Atom1,变量中的值有空格
#直接报错    -bash: people: 未找到命令
echo ${Atom1}   #显示该变量的值
#尝试显示Atom1的变量的值,显示值为空,原因是定义失败,等于没定义

在这里插入图片描述
单引号:单引号会直接打印出单引号里的值,不会去关注里面有没有变量啊什么的,会原封不动的把单引号里面的值打印出来。

Atom2=good    #首先定义一个变量Atom2
Atom3='two ${Atom2}'  #在定义一个变量Atom3,观察其变量值,看看打 印结果是什么
echo ${Atom3}  #显示该变量的值
#打印结果为 :two ${Atom2}
 

在这里插入图片描述

双引号:如果我们想在变量值里加上其他变量并且打印出其变量的值,这时候我们就可以使用双引号。

Atom4=good    #首先定义一个变量Atom4
Atom5="two ${Atom2}"  #在定义一个变量Atom5,这次使用双引号观察其 变量值,看看打印结果是什么
echo ${Atom5}  #显示该变量的值
#Atom5的变量的值为two good
 

在这里插入图片描述

2.1 获取字符串的长度

在变量名前加#号即可
在这里插入图片描述

2.2 字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:

运算符 说明 举例
= 或 == 检测两个字符串是否相等,相等返回 true。建议使用== [ $a = $b ] 返回 false。
!= 检测两个字符串是否不相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否不为 0,不为 0 返回 true。 [ -n "$a" ] 返回 true。
$ 检测字符串是否不为空,不为空返回 true。 [ $a ] 返回 true。

字符串运算符实例如下:

a="abc"
b="efg"

if [ $a == $b ]
then
   echo "$a = $b : a 等于 b"
else
   echo "$a != $b: a 不等于 b"    #执行打印
fi

if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"    #执行打印
else
   echo "$a != $b: a 等于 b"
fi

if [ -z $a ]
then
   echo "-z $a : 字符串长度为 0"
else
   echo "-z $a : 字符串长度不为 0"   #执行打印
fi

if [ -n "$a" ]
then
   echo "-n $a : 字符串长度不为 0"   #执行打印
else
   echo "-n $a : 字符串长度为 0"
fi

if [ $a ]    
then
   echo "$a : 字符串不为空"    #执行打印
else
   echo "$a : 字符串为空"
fi

注意: shell的 if 语法对于未定义的变量不会报错,默认未定义的变量是长度为0的空串 ,可以简单的把shell中的 空,理解为Java中的 空字符串”“ 而不是null,因此 在shell中 计算 ""的长度 不会java中的空指针错误。

结论,下面的效果是等价的

a=""
a=
a=''
echo $b    # 即使b尚未定义,也不会报错
echo "${#c}"  #打印 0

验证过程,我们未定义变量c,然后执行过程没有报错,并且看看有关判断结果:

if [ -z $c ]
then  
   echo "-z $c : 字符串长度为 0"       	 #执行打印
else
   echo "-z $c : 字符串长度不为 0"  
fi

if [ -n "$c" ]
then
   echo "-n $c : 字符串长度不为 0"  
else
   echo "-n $c : 字符串长度为 0"			 #执行打印
fi

if [ $c ]    
then
   echo "$c : 字符串不为空"   
else
   echo "$c : 字符串为空"			 #执行打印
fi

虽然空串长度结果为0,但是我们在shell脚本中,如果需要对

3、数组

在Shell中,仅支持一维数组,元素下标由0开始,可通过下标进行赋值和取值操作,Shell 数组用括号来表示,元素用"空格"符号分割开。

F=(A 123 ATOM 你好)   #定义一个数组F

在数组中可以使用下标来取出来对应的值,${变量名[下标]}

F=(A 123 ATOM 你好)   #定义一个数组F
 
echo ${F[1]}     #打印出数组中下标为1的值
#打印的是下标为1的值 123

在这里插入图片描述

3.1 数组长度

在数组中可以使用#来计算数组的长度,${#变量名[*]} 或者 ${#变量名[@]}

注意:${#变量名[*]} 或者 ${#变量名[@]} 中的#号是统计长度,如果去掉,就是取值(后面会提到取值的示例)

F=(A 123 ATOM 你好)   #定义一个数组F
 
 
echo ${#F[*]}     #打印出数组中元素的个数
#打印结果为:4      数组中一共有4个元素
 
echo ${#F[@]}     #打印出数组中元素的个数
#打印结果为:4      数组中一共有4个元素

在这里插入图片描述

3.2 要获取数组中的所有元素

可以有以下几个方法,${变量名[*]} 或者 ${变量名[@]} 或者 "${变量名[@]}" ,即双引号;
如果想以一个元素的形式输出的话需要加上双引号"${#变量名[*]}"。(使用"${变量名[@]}"输出的也是多个元素的形式)

F=(A 123 ATOM 你好)   #定义一个数组F
 
 
echo ${F[@]}     #打印出数组中的所有元素
#打印出了所有的元素 A 123 ATOM 你好
 
echo "${F[@]}"     #打印出数组中的所有元素
#打印出了所有元素    A 123 ATOM 你好
 
echo "${F[*]}"     #打印出数组中的所有元素
#打印出了所有元素    A 123 ATOM 你好
 
echo "${F[*]}"     #打印出数组中的所有元素,以一个字符串处理
#打印出了所有元素   但是这个是以一个字符串打印出来的 A 123 ATOM 你好
 
 
for i in ${F[@]};do echo $i;done      #使用for循环打印下就能看出来了
#打印结果
A
123
ATOM
你好
 
for i in "${F[@]}";do echo $i;done      #使用for循环打印下就能看出来了
#打印结果
A
123
ATOM
你好
 
for i in ${F[*]};do echo $i;done      #使用for循环打印下就能看出来了
#打印结果
A
123
ATOM
你好
 
for i in "${F[*]}";do echo $i;done      #使用for循环打印下就能看出来了
#打印结果 A 123 ATOM 你好
 

在这里插入图片描述

3.3 迭代数组中的元素

参考3.2小节中的示例,使用下面的格式

for i in ${F[*]};do 
    echo $i;
    xxxx
    xxxx
done

for i in ${F[@]};do 
    echo $i;
    xxxx
    xxxx
done

参考

Linux与Shell学习–shell系列4–常用的数据类型(数字、字符串和数组)

  • 8
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值