Shell-算数计算

Shell-算数计算

二月 23, 2021

算数运算符

expr求值表达式

可以实现整数计算

可以对字符串进行处理(例如计算字符串长度、字符串比较、字符串匹配、字符串提取)

1
2
3
expr 1 + 1 #直接输出结果

res=`expr 1 + 1` #返回结果给res变量
运算符 说明 举例
+ 加法 expr $a + $b结果为3
- 减法 expr $a - $b结果为-1
* 乘法 expr $a \* $b结果为2
/ 除法 expr $a / $b结果为2
% 取余 expr $a % $b结果为0
= 赋值 a=$b把变量b赋值给变量a

其中a = 1,b = 2

注意:四则运算中使用()也需要转义\( 1 + 1 \)

比较运算符

整数比较

运算符eq 说明 举例
-eq equals检测两个数是否相等,相等返回0,否则返回1。 [ $a -eq $b ]返回1
-ne not equals检测两个数是否不相等,不相等返回ture [ $a -ne $b ]返回0
-gt greater than 检测左边数是否大于右边数,大于返回0,否则返回1 [ $a -gt $b ]返回1
-lt lower than 检测左边数是否小于右边数,小于返回0,否则返回1 [ $a -lt $b ]返回0
-ge greater equals检测左边数是否大于等于右边数,大于等于返回0,否则返回1 [ $a -ge $b ]返回1
-le lower equals 检测左边数是否小于等于右边数,小于等于返回0,否则返回1 [ $a -le $b ]返回0
< 检测左边数是否小于右边数,小于返回0,否则返回1 (($a<$b))返回1
<= 检测左边数是否小于等于右边数,小于等于返回0,否则返回1 (($a<=$b))返回0
> 检测左边数是否大于右边数,大于返回0,否则返回1 (($a>=$b))返回1
>= 检测左边数是否大于等于右边数,大于等于返回0,否则返回1 (($a>=$b))返回0
== 检测两个数是否相等,相等返回0,否则返回1。 (($a==$b))返回0
!= 检测两个数是否不相等,不相等返回true (($a!=$b))返回1

其中a = 1,b = 1

注意:整数比较运算符仅支持整数运算,不支持浮点数与字符串

[](())的区别:

  • []参数为-eq -gt -ge -lt -le ne
  • ()参数为 < <= > >= == !=

字符串比较运算符

可以比较数字与字符串

运算符 说明 举例
==或者= 相等,用于比较两个字符串或数字,相同返回0 [ $a == $b ]返回1
[ $a = $b ]返回1
[[ $a == $b ]]返回1
[[ $a = $b ]]返回1
!= 不相等,用于比较两个字符串或数字,不相同返回0 [ $a != $b ]返回0
[[ $a != $b]]返回0
< 小于,用于比较两个字符串或数字,小于返回0,否则返回1 [ $a \< $b ]返回0
[[ $a < $b]]返回0
> 大于,用于比较两个字符串或数字,大于返回0,否则返回1 [ $a \> $b ]返回1
[[ $a > $b]]返回1
-z 检测字符串长度是否为0,为0返回true [-z “$a”]返回false
-n 检测字符串长度是否不为0,不为0返回true [-n “$a”]返回true
$ 检测字符串长度是否为空,不为空返回true [ $a ]返回true

其中a=”abc”,b=”efg”

注意:字符串比较没有<=,但是可以通过[[ "a" < "b" && "a" == "b" ]]


[][[]]的区别:

  • 区别①

    []会有word splitting发生,即将含有空格字符的字符串进行分拆分割后再进行比较

    [[]]不会有word splitting发生

  • 区别②

    []不会对<进行转义,需要手动转义

    [[]]自动对<进行转义,不需要手动转义

布尔运算符

运算符 说明 举例
! 非运算,取反,表达式为true则返回false,否则返回true [ ! 表达式 ]取反
-o or或运算,有一个表达式为true则返回true [ 表达式1 -o 表达式2 ]
-a and与运算,两个表达式都为true才返回true [ 表达式1 -a 表达式2 ]

注意:布尔运算符需要与[]test命令配合使用才有效

逻辑运算符

运算符 说明 举例
&& 逻辑AND [[ 表达式1 && 表达式2 ]]
|| 逻辑OR [[ 表达式1 || 表达式2 ]]
! 逻辑NOT [[ ! 表达式 ]]

注意:

  • 使用&&||需要配合[[]](())使用,否则会报错(╯▔皿▔)╯
  • !可以配合[][[]],但是不可以配合(())

逻辑运算符与布尔运算符区别:

  • 布尔运算符:! -o -a 且必须搭配[]test命令使用
  • 逻辑运算符: || &&且必须搭配[[]](())使用,!不能配合(())使用

文件测试运算符

用于检测文件

检测文件是否存在\是否可读\是否可执行\是否为空\是否可写\是否为名录\是否是普通文件

linux系统文件类型

-:普通文件

d:目录文件

l:链接文件

b:块设备文件

对应计算机硬件,以块为单位传输数据

c:字符设备文件

对应计算机硬件,以字符为单位传输数据

p:管道文件

文件属性检测

操作符 说明 举例
-b file 检测文件是否为块设备文件,是返回true [ -b $file ]返回false
-c file 检测文件是否为字符设备文件,是返回true [ -c $file ]返回false
-d file directory,检测文件是否为目录,是返回true [ -d $file ]返回false
-f file file,检测文件是否为普通文件,是返回true [ -f $file ]返回ture
-g file 检测文件是否设置了SGID位,是返回true [ -g $file ]返回false
-k file 检测文件是否设置了粘着位,是返回true [ -k $file ]返回false
-p file 检测文件是否为有名管道文件,是返回true [ -p $file ]返回false
-u file 检测文件是否设置了SUID位,是返回true [ -u $file ]返回false
-r file read,检测文件是否可读,是返回true [ -r $file ]返回true
-w file write,检测文件是否可写,是返回true [ -w $file ]返回true
-x file execute,检测文件是否可执行,是返回true [ -x $file ]返回true
-s file size,检测文件是否为空,是返回true [ -s $file ]返回true
-e file exists,检测文件是否存在,是返回true [ -e $file ]返回true
file1 -nt file2 newer than,检测文件1是否比文件2新,是返回true [ file1 -nt file2 ]返回
file1 -ot file2 older than,检测文件1是否比文件2旧,是返回true [ $file1 -ot file2 ]返回
-S file socket,检测文件是否为socket,是返回true [ -S $file ]返回false
-L file link,检测文件是否存在并且是一个符号链接,是返回true [ -L $file ]返回false

注意:

  • 配合[][[]]均可

  • file需要为路径字符串

计算命令

expr命令详解

优点:可以直接输出整数表达式结果

缺点:

  1. 表达式内引用变量需要使用$
  2. 特殊字符需要转义
  3. 只能计算一个表达式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#计算语法
expr 1 + 1 #返回2
expr \( 10 + 10 \) \* 2 + 100 #返回140
res=`expr 1 + 1` #输出结果给res变量

#字符串语法
#计算字符串长度
expr length "jiajuu" #返回6
#截取字符串
expr substr "jiajuu" 1 3 #返回jia
#获取第一个字符再字符串出现的位置
expr index "jiajuu" i #返回2
#正则表达式匹配
expr match "jiajuu" ".*a" #返回3
expr "jiajuu" : ".*a" #返回3

(())命令详解

(())可用于进行数学运算表达式的执行

并且可以使用$获取(())表达式命令中的结果


优点:

  1. 直接计算表达式,特殊符号不需要转义
  2. 可以多个表达式赋值

缺点:需要变量获取结果才能输出

(悄悄话:直接输出计算结果推荐方式(b( ̄▽ ̄)d))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#计算完成给变量赋值,注意:不需要添加"$",能自动解析变量
((a=1+6))
((b=a-1))
((c=a+b))

#"(())"前添加"$"获取"(())"命令的结果
a=$((1+6))
b=$((a-1))
c=$((a+b))she

#"(())"进行逻辑运算,常用于if语句
((a>7 && b==c))

#输出运算结果
echo $((a+10))

#对多个表达式同时进行计算,用","进行分割
((a=3+5,b=a+10))

let命令详解

(())命令在数字计算方面一样,

let是最简洁的整数运算赋值命令,

但是功能没有(())命令功能强大.let只能用于赋值计算,不能直接输出,也不可以进行条件判断。


优点:赋值简单,特殊符号不需要转义

缺点:无法直接输出结果,需要变量获取结果再输出

(悄悄话:赋值操作推荐方式(b( ̄▽ ̄)d))

1
2
3
4
5
6
7
let a=1+6 #计算1+6赋值给变量a

let b=a-1 #将变量a-1赋值给变量b

let c=a+b #将变量a+变量b赋值给变量c

let a=1+6 b=a-1 c=a+b #多个表达式计算赋值

$[]命令详解

(())let命令类似,

但是$[]只能进行整数运算,且只能对单个表达式进行计算求值和输出

而且内部不能对变量赋值


优点:赋值简单,特殊符号不需要转义

缺点:不能多表达式运算

1
2
3
4
a=$[1+6]
b=$[a-1]
c=$[a+b]
echo "$[1+6],$[a-1],$[a+b]"

bc命令详解

Bash Shell内置了对整型运算的支持,但是不提供符点运算

bc命令可以对符点型进行方便的符点运算,是linux简单的计算器

bc命令不仅可以进行任意精度的符点计算,还能进行进制的转换

1
bc [options] [参数]

options

选项 说明
-h help,帮助信息
-v version,显示命令版本信息
-l mathlib,使用标准数学库,例如使用内置函数就需要使用这个选项
-i interactive,强制交互
-w warn,显示POSIX的警告信息
-s standard,使用POSIX标准来处理
-q quiet,不显示欢迎信息(默认bc启动会有欢迎信息)

参数

指定包含计算任务的文件

1
bc task.txt

task.txt文件

1
2
108*67+12345
58+2007*11

内置变量

变量名 作用
scale 指定精度,即小数点后的位数。默认为0,不适用小数部分
ibase 指定输入的数字进制。默认为十进制
obase 指定输出的数字进制。默认为十进制
last或者. 获取最近计算打印结果的数字

内置数学函数

需要把options设为-i,才能使用内置数学函数

函数名 作用
s(x) 计算x的正弦值,x是弧度值
c(x) 计算x的余弦值,x是弧度值
a(x) 计算x的反正切值,返回弧度值
l(x) 计算x的自然对数
e(x) 计算e的x次方
j(n,x) 计算从n到x的阶数

借助管道使用bc运算

1
2
3
4
5
6
7
8
9
10
#直接进行bc的表达式
echo "scale=2;9*6/3.3" | bc

#引用Shell变量
a=2
echo "b=$a+2;b" | bc #其中的b是bc命令中的变量,不是Shell变量

#将bc计算结果赋值给Shell变量
value = `ehco "1+1" | bc` #所有linux系统均支持的方式
value = $(ehco "1+1" | bc) #不是所有linux均支持

表达式必须符合bc命令要求的公式

表达式可以引用shell变量

输入重定向到bc运算

特点类似于文件中输入,支持多行表达式(b( ̄▽ ̄)d)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#方式一,使用``
value=`bc << EOF
ibase=10;
obase=2;
b=9*9
EOF
`

#方式二,使用$()
value=$(bc << EOF
ibase=10;
obase=2;
b=9*9
EOF
)