首页 > 代码库 > 第二章 数学运算、数组、文字处理

第二章 数学运算、数组、文字处理

第二章 数学运算、数组、文字处理.md

知识要点

  • 数学运算
  • 数组的使用
  • seq tr sort uniq cut 等命令

数学运算

整数运算

常用的运算符

  • 加法运算符:+
  • 减法运算符:-
  • 乘法运算符:/
  • 求模运算符:%
  • 求幂运算符:**

常用整数运算

  1. 第一种
  2. declare -i a=10*20; echo $a 少用
  3. 第二种
  4. a=$(expr 10‘*‘20); echo $a 少用
  5. 第三种
  6. a=$[10*2]; echo $a []中的变量无需加$
  7. echo $[RANDOM%10] 0-9的随机数
  8. 第四种
  9. a=$((10*20)); echo $a $(())中的变量无需加$
  10. echo $((RANDOM%10)) 0-9的随机数
  11. 第五种(推荐)
  12. ((a=10*20)); echo $a 常用来赋值
  13. ((a++)) (())中的变量无需加$
  14. 第六种
  15. let a=10*20; ehco $a 常用来赋值
  16. let i++
  17. let i+=10

条件测试
双圆括号整数值比较(推荐方法)
格式((整数1 操作符 整数2))
操作符: ==, >, < , != , <= , >=

技术分享

小数运算

注意bash只支持整数的运算,浮点数的运算用bc。

例如

  1. # echo 4/3 | bc
  2. 1
  3. # echo "scale=2;4/3"/bc
  4. 1.33

案例1

技术分享

案例2

技术分享

案例3
脚本实现显示现在离放学还有多长时间,放学时间是17:30,显示效果如下
技术分享

数组的基本用法

数组是一个由若干同类型变量组成的集合,引用这些变量时可以使用同一个名字。数组均由连续的存储单元组成,最低地址对应于数组的第一个元素,最高地址对应于最后一个元素
bash shell只是支持一维数组,数组从0开始标号,以array[x]表示数组元素,那么,array[0]就表示array数组的第一个元素,array[1]表示array数组的第二个元素,array[x]表示array数组的第x+1个元素。

声明数组
格式:数组名=(参数1 参数2 …)
多个ip地址存入数组中

  1. [root@localhost ~]# ip=( 192.168.0.1 192.168.0.2 192.168.0.3 )
  2. [root@localhost ~]# echo ${ip[0]}
  3. 192.168.0.1
  4. [root@localhost ~]# echo ${ip[1]}
  5. 192.168.0.2
  6. [root@localhost ~]# echo ${ip[2]}
  7. 192.168.0.3
  8. [root@localhost ~]# ip[3]=192.168.0.4
  9. [root@localhost ~]# echo ${ip[3]}
  10. 192.168.0.4

数组的基本用法
查看数组里面的元素个数
echo {#ip[@]} 查看数组元素个数  
echo
{ip[@]} 查看数组所有元素
echo ${!ip[@]} 查看数组下标
unset ip[1] 清除数组中的某个元素
unset ip 清除整个数组。

利用数组获得当前主机的网关

  1. [root@localhost ~]# vi gate.sh
  2. #!/bin/bash
  3. a=($(route -n | grep ‘^0.0.0.0‘))
  4. echo gateway is ${a[1]}
  5. [root@localhost ~]# bash gate.sh
  6. gateway is 10.10.10.254

将变量替换为数组

  1. [root@localhost ~]# var1="aaa bbb ccc"
  2. [root@localhost ~]# var2=($var1)

关联数组
数组bash 4.0开始支持关联数组,rhel5不支持

  1. [root@localhost ~]# declare -A name
  2. [root@localhost ~]# name=([user]=txy [pwd]=123 [age]=18)
  3. [root@localhost ~]# echo ${name[@]}
  4. 123 txy 18
  5. [root@localhost ~]# echo ${#name[@]}
  6. 3
  7. [root@localhost ~]# echo ${!name[@]}
  8. pwd user age
  9. [root@localhost ~]# echo ${name[user]}
  10. txy

案例4
利用数组从文件中随机挑选姓名的脚本
有一个包含姓名的文件,姓名用空格隔开

seq命令

seq
用途:打印出一串有序的数字
格式:seq [选项] 数字范围
-s:指定分隔符
-w:指定同等宽带输出

  1. [root@localhost ~]# seq -s " " 90 100
  2. 90 91 92 93 94 95 96 97 98 99 100
  3. [root@localhost ~]# seq -s "**" 90 100
  4. 90**91**92**93**94**95**96**97**98**99**100
  5. [root@localhost ~]# seq -s "**" -w 90 100
  6. 090**091**092**093**094**095**096**097**098**099**100
  7. 6

脚本实例

编写脚本创建用户,要求根据输入的用户名前缀和数目自动创建

  1. #!/bin/bash
  2. read -p "please input username prefix: " USER
  3. read -p "the number of new users: " NUM
  4. for i in $(seq -w $NUM)
  5. #for i in {01..$NUM}
  6. do
  7. useradd $USER$i && echo "$USER$i has been created"
  8. done
  9. }

实验案例5(没有意义所以不写)

利用数组和seq命令实现双色球彩票脚本
32个红球中随机选6个,16个篮球中随机选1个
建议使用for循环

tr命令

tr字符转换工具
只能对stdin操作,不能直接对文件操作

使用tr转换字符

tr set1 set2
使用set2中的字符替换掉set1中同一位置的字符

  1. pecho 123456 | tr 345 abc
  2. ptr 123 abc < aa
  3. ptr ‘[a-z]’ ‘[A-Z]’ < /etc/hosts
  4. pecho $PATH | tr ‘:‘ ‘\n‘

使用tr删除字符

tr -d set
将stdin中数据流删除与set相同的字符

  1. pecho 123456 | tr -d 345
  2. ptr -d ‘[0-9]’ < /etc/hosts
  3. p df -h | tr -d %
  4. pwho | tr -d ‘

使用tr压缩字符

tr -s set
将连续相同的字符压缩成一个字符
pecho 112233444555666 | tr -s 345
pifconfig | tr -s ‘ ‘

tr -s set1 set2
先将set1 替换成set2 再压缩
pecho 112233444555666 | tr -s 345 abc
pecho 112233444555666 | tr 345 abc | tr -s abc
pwho | tr -s ‘ ‘ ‘\n’

sort命令

sort 命令
默认按每行的第一个字符排序
-n:按整数进行排序
-r:递减排序

指定排序键

指定按哪一列数据进行排序
-k:指定哪一列为排序键
cat tt | sort -n -k4

指定字段分隔符

-t:指定字段分隔符(默认是空白)
sort -t : -n -k3 /etc/passwd

uniq

删除经过排序后的数据的重复记录
通常和sort连用
sort -n tt | uniq

数据的实例统计

-c:统计特定记录出现的次数
cat tt| uniq -c

-u:只显示唯一的行
cat tt | uniq -u

-d:只显示重复的行
cat tt | uniq -d

数据提取cut

cut命令
从文本文件或者文本流中提取文本列
cut -选项 提取范围 文本文件

常见的选项

-c:从指定提取范围中提取字符
-f:从指定提取范围中提取字段

提取范围

n:第n项
n-:从第n到行尾
-m:行首到第m项
n,m:第n项到第m项
n-m:第n项到第m项

示例

cut -c命令

ls -l | cut -c10
who | cut -c 20-40
cut -c -10 /etc/passwd

cut -f命令

-d:指定分隔符默认是Tab
cut -d “:” -f 1,7 /etc/passwd
who | cut -d ‘ ‘ -f1,6

实验案例6

命令练习
只显示/boot目录下所有对象的实际空间,并按由小到大排序
统计/etc/passwd中每种shell的被使用次数
用fdisk -l命令只显示出分区和文件系统的类型
统计/etc/passwd文件中sbin这个单词出现多少次
只显示网卡eth0的IP地址

实验案例7

编写脚本统计/var/log/secure文件中ssh访问密码错误的用户次数(包括不存在的用户)和IP次数,要从小到大排序,显示效果参考如下
技术分享

实验案例8

编写脚本统计指定目录下面文件占用空间大小超过10M的文件的数目和大小总和

使用1个位置参数指定目录的绝对路径
技术分享

实验案例9

有一个FTP的日志文件xferlog(服务器上下载),要求根据下列的要求对这个日志文件进行处理

统计每个ip下载的文件的总大小,要显示出总大小大于2M的IP和总大小,按降序显示(以MB为单位)

技术分享

第二章 数学运算、数组、文字处理