shell判断、循环语法以及sed流式编辑器

认识shell
一、 shell 基础
1 shell 概念
shell 英文翻译过来是外壳的意思,作为计算机语言来理解可以认为它是 操作系统的外壳。可以通过shell 命令来操作和控制操作系统,比如 Linux中的 shell 命令就包括 ls cd pwd 等等。
shell 在内核的基础上编写的一个应用程序,它连接了用户和 Linux 内 核,从而让用户能够更加便捷、高效、安全的使用 linux 内核,这其实 就是 shell 的本质。
使用专业术语的说法来解释, Shell 其实是一个命令解释器,它通过接 受用户输入的 Shell 命令来启动、暂停、停止程序的运行或对计算机进 行控制。
2 shell 脚本
shell 脚本就是由 Shell 命令组成的执行文件,将一些命令整合到一个文件 中,进行处理业务逻辑,脚本不用编译即可运行,它从一定程度上减轻 了工作量,提高了工作效率,还可以批量、定时处理主机,方便管理员 进行设置或者管理。
3 shell 脚本编写注意事项
shell 命名 : shell 脚本名称命名一般为英文、大写、小写、后缀以 .sh 结尾
不能使用特殊符号、空格
名称要写的一眼可以看出功能,也就是顾名思义 shell脚本首行需要 #!/bin/bash 开头
shell 脚本变量 不能以数字、特殊符号开头 ,可以使用下划线 _ ,但不能 用破折号——
二、 shell 脚本的构成
脚本声明
注释信息
可执行语句
三、编写 shell 脚本
1 、伟大编程项目 ——Hello World
'Hello,World!' 中文意思是 你好,世界 。因为 The C Programming Language 中使用它做为第一个演示程序,后来的程序员在学习编程或 进行设备调试时延续了这一习惯。
执行 shell 脚本的几种
bash 脚本名称
source 脚本名
在当前环境生效,其他方法都是在开一个
shell 进程
sh 脚本名称
添加 x 权限, ./ 脚本名称
shell 脚本其实就是有序执行命令条件
[root@localhost ~] # touch hello.sh
[root@localhost ~] # vim hello.sh #!/bin/bash
echo "Hello World!" # 输出 “Hello World
:wq
[root@localhost ~] # bash hello.sh # shell 脚本的⽅ 1
Hello World!
[root@localhost ~] # sh hello.sh # ⾏ shell脚本的 2
Hello World!
[root@localhost ~] # chmod +x hello.sh # shell 脚本 的⽅ 3
[root@localhost ~] # ll hello.sh
-rwxr-xr-x . 1 root root 32 6 14 14 :22 hello.sh
[root@localhost ~] # ./hello.sh
Hello World!
[root@localhost ~] # source ./hello.sh # 只在当前环境生效, 其他方法是另外再开一个shell
Hello World!
[root@localhost ~] # vim hello.sh # 修改 hello 脚本
#!/bin/bash echo "Hello World!"
ls -lh /
df -hT
:wq
[root@localhost ~] # sh hello.sh
Hello World!
2 、编写 nginx 安装脚本
   1. 安装依赖环境
   2. 下载 nginx 压缩包
   3. 解压
   4.make make install 安装
   5. 按照顺序执行指令
[root@localhost ~] # vim /root/shell/install_nginx.sh
#!/bin/bash
yum -y install gcc gcc-c ++ make pcre-devel openssl-devel
wget
cd /usr/local/src/
wget 'http://nginx.org/download/nginx-1.22.1.tar.gz'
tar xf nginx-1.22.1.tar.gz
cd nginx-1.22.1
./configure --prefix = /usr/local/nginx
make -j 4
make install
:wq
# 逻辑顺序:先安装依赖关系,再进入到系统默认的安装包目录 src ,使用 wget
命令从网上下载 nginx1.22.1 版本的安装包,然后解压,再移动到 nginx
装目录,执行编译安装(预配置,编译,编译安装)
四、变量
1 、概念
变量用来存放系统或用户需要使用的特定参数或者值,变量的值可以根 据用户设定或者系统环境变化而相应变化,在Shell 脚本中使用变量,可 使脚本更加灵活,适应性更强。 与变量相对应的是常量,常量例如“Hello World” ,是不可改变的 变量可以给个变量名,假如为name ,值是可变的
2 、变量注意事项
变量命名规则: 必须由大写字母、小写字母、下划线、数字,并且首字 母不能是数字
在变量命名时:建议也简写出该变量是什么用处
变量值的类型:值的类型会分为整型、浮点型、字符串型、布尔型等, 而且使用变量需要指定类型Shell 默认的变量类型都是字符串,无需指 定类型
3 、变量的分类
1 )自定义变量
由用户自己定义、使用和修改
[root@localhost ~] # A=1314 # 左边是变量名、右边是值
[root@localhost ~] # echo $A
1314
[root@localhost ~] # unset A # 清除变量
[root@localhost ~] # echo $A
变量名 = 值中,等于号 = 之前和之后不能有空格,比如: name = yang
这样是错的, name=yang 才对
变量名 = 值中,值内如果输入数学算式,是没办法算出结果的,只会输
出字符串。
2 )环境变量
由系统维护,用于设置工作环境
$PWD
$SHELL
$USER
$PATH
[root@localhost ~] # env # 查看所有环境变量
[root@localhost ~] # echo $PWD
/root
[root@localhost ~] # echo $SHELL
/bin/bash
[root@localhost ~] # echo $USER
root
[root@localhost ~] # echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
其中 PATH 变量用于设置可执行程序的默认搜索路径,可以修改全局变 量文件/etc/profile 或修改某用户家目录下的 ~/.bash_profile 文件永久改 变环境变量。
3 )位置变量
通过命令行给脚本程序传递参数 ( 也属于预定义变量 ) 为了在使用Shel 脚本程序时,方便通过命令行为程序提供操作参数, Bash引入了位置变量的概念位置变量有 n n 1~9 之间的数字
$0 :第一个字段表示命令名或脚本名称
$1 :脚本要处理的第一个参数
$2 :脚本要处理的第二个参数
....
Shell 脚本最多可以直接处理 9 个参数
[root@localhost shell] # vim ip.sh
#!/bin/bash
ifconfig $1 | grep -w inet | awk '{print $2}' # 设置 个参数
:wq
[root@localhost shell] # sh ./ip.sh ens32
192 .168.100.100
[root@localhost shell] # vim ip.sh
#!/bin/bash
ifconfig $1$2 | grep -w inet | awk '{print $2}' # 设置两个参 数
:wq
[root@localhost shell] # sh ./ip.sh ens 32
192 .168.100.100
4 )预定义变量
Bash 中内置的一类变量,不能直接修改
预定义变量是 Bash 程序预先定义好的一类特殊变量,用户只能使用预定
义变量,而不能创建新的预定义变量,也不能直接为预定义变量赋值。
$* :将所有参数作为整体
[root@localhost shell] # vim ip.sh
#!/bin/bash
ifconfig $1 | grep -w inet | awk '{print $2}' # 设置 个参数
:wq
[root@localhost shell] # sh ./ip.sh ens32
192 .168.100.100
[root@localhost shell] # vim ip.sh
#!/bin/bash
ifconfig $1$2 | grep -w inet | awk '{print $2}' # 设置两个参
:wq
[root@localhost shell] # sh ./ip.sh ens 32
192 .168.100.100
[root@localhost shell] # $@ :单个参数的组合,每个参数占一行
$0 :保存了脚本名称
$? :保存命令或脚本的执行状态码
$# :保存脚本要处理的参数的个数
[root@localhost shell] # vim hehe.sh
#!/bin/bash
for x in " $* " # 将所有参数整合到一起,总共列为一行
do
echo $x
done
for y in " $@ " # 将所有参数单个列出,每个参数单列一行
do
echo $y
done
:wq
[root@localhost shell] # sh ./hehe.sh 1 2 3 4 5 6 # 查看$* $@ 的区别
1 2 3 4 5 6 # $* 的结果
1
2
3
4
5
6 # $@ 的结果
[root@localhost shell] # vim hehe.sh
#!/bin/bash
for x in " $* "
do
echo $x
done
for y in " $@ "
do
echo $y
done
echo " 该脚本是 : $0 "
echo " 此脚本 共处理了 $# 个参数 "
:wq
[root@localhost shell] # sh hehe.sh 1 2 3 4 5 6
1 2 3 4 5 6
1
2
3
4
5
6
该脚本是 :hehe.sh # $0 的结果,也就是该脚本的名称
此脚本 共处理了 6 个参数 # $# 的结果,执行脚本时,输入了多少参 数
4 、变量的定义与输出
1 )定义一个新的变量
格式:变量名 = 变量值
注意:变量名必须以字母或下划线开头,严格区分大小写
2 )变量符号运用
双引号:允许通过 $ 符号引用其他变量值
单引号:禁止引用其他变量值, $ 视为普通字符
反撇号: 或 $(): 命令替换,提取命令的执行结果
[root@localhost shell] # X=aaa
[root@localhost shell] # echo "$X" # 双引号可以使用变量
aaa
[root@localhost shell] # echo '$X' # 单引号只显示符号内的 字符
$X
[root@localhost shell] # ip1=`ifconfig ens32 | grep -w inet | awk '{print$2}'` # ``反撇号可以引用命令
[root@localhost shell] # ip2=$(ifconfig ens32 | grep -w inet | awk '{print$2}') # $()与反撇号作用相同
[root@localhost shell] # echo $ip1
192 .168.100.100
[root@localhost shell] # echo $ip2
192 .168.100.100
[root@localhost shell] # x=100
[root@localhost shell] # y=50
[root@localhost shell] # z=`expr $x + $y` # 整数运算
[root@localhost shell] # echo $z
150
[root@localhost shell] # x=1.4
[root@localhost shell] # expr $x + 1 # 判断是否为浮点数
expr: 整数参数
[root@localhost shell] # [ $? -ne 0 ] && echo "x 为浮点数 "
x 为浮点数
3 )输入和输出
输入格式: read [-p " 显示的提示信息 "] 变量名
输出格式: echo $ 变量名
[root@localhost shell] # read x y # ,变量输入,在下 一行输入
1 3
[root@localhost shell] # echo $x $y # 输出,直接输出变量
1 3
[root@localhost shell] # read -p " 请输 你要赋值的变量值 " x y
请输 你要赋值的变量值 1 5
[root@localhost shell] # echo $x $y
1 5
[root@localhost shell] # vim ip.sh # 编写一个查看 IP 的脚 本,内容如下
#!/bin/bash
read -p " 请输 名称: " x # 输入 x 变量等于什么,脚本内不 用写,命令行输入该变量x 等于什么即可,该变量 x 可在脚本内引用
ifconfig $x | grep -w inet | awk '{print $2}'
:wq
[root@localhost shell] # sh ip.sh
请输 名称: ens32
192 .168.100.100
[root@localhost shell] # sh ip.sh
请输 名称: lo
127 .0.0.1
[root@localhost shell] # vim read.sh # 编写输入账号密码的脚 本,内容如下
#!/bin/bash
read -p " 请输 您的姓名: " name # 该变量 name 是在命令行输入 的,相当于变量=
read -p " 请输 您的密码: " passwd # 该变量 passwd 是在命令行输入 的,相当于变量=
if [ $passwd = "123456" ]; then # if 判断语句,如果 (if) 某某 等于某某,那么(then) 执行什么命令,否则 (else) 执行什么命令,结尾 fi
echo " 你好, $name !"
else
echo " 抱歉,您输 的密码不正确! "
fi
:wq
[root@localhost shell] # sh read.sh
请输 您的姓名: admin
请输 您的密码: 112233
抱歉,您输 的密码不正确!
[root@localhost shell] # sh read.sh
请输 您的姓名: admin
请输 您的密码: 123456
你好, admin !
5 、变量的作用范围
默认情况下,新定义的变量只在当前 Shell 环境中有效,因此称为局部变
量。当进入子程序或新的子 shell 时,局部变量将无法再使用。
为了使用户定义的变量在所有子 Shell 环境中能够继续使用,减少重复设
置工作,可以通过内部命令 export 将指定的变量导出为 全局变量
格式 1 export 变量名
格式 2 export 变量名 =
[root@localhost shell] # x=aaa
[root@localhost shell] # export y=bbb # 使 y=bbb 导出为 全局变量,即使下次更新环境变量,y 也会生效,相当于在 /etc/profile 内永 久赋值
[root@localhost shell] # hostname shell
[root@localhost shell] # bash
[root@shell shell] # echo $x
[root@shell shell] # echo $y
bbb
6 、变量的数学运算
1 )整数运算
格式: expr 变量 1 运算符 变量 2 运算符 变量 3....
运算符: + - * / + - × ÷
[root@shell shell] # x=123
[root@shell shell] # y=111
[root@shell shell] # expr $x + $y #
234
[root@shell shell] # expr $x - $y #
12
[root@shell shell] # expr $x \* $y #
13653
[root@shell shell] # expr $x / $y #
1
[root@shell shell] # expr $x % $y # 余数计算
12
2 )精度计算
[root@shell shell] # yum -y install bc # 精度计算前,先 安装bc 这个软件才可进行,否则只能进行整数运算
上次元数据过期检查: 2:45:58 前,执 2023 06 14 星期三 22 时 21分 58 秒。
软件包 bc-1.07.1-5.el8.x86_64 已安装。
依赖关系解决。
需任何处理。
完毕!
[root@shell shell] # x=123
[root@shell shell] # y=111
[root@shell shell] # echo "scale=5; $x / $y" | bc
1 .10810
判断语法
一、条件判断
Shell 的返回值:运行一条命令,都会有一个返回值。 0 代表执行正常,非 0 代表命令执行异常。
[root@localhost test] # ls /
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
[root@localhost test] # echo $? # $? 保存了上条命令的返回值, 0 表示执行成功,非 0 表示执 行失败
0
[root@localhost test] # ls /haha
ls : 法访问 '/haha' : 没有那个 件或
[root@localhost test] # echo $?
2
二、 if 条件判断语句
1 if 单分支语句
if 条件判断 ; then
条件成 的命令 ( 可以有多个命令,命令执行方式为逐行执行要么全执行,要么全不执行 )
fi
2 if 多分支语句
if 条件判断 ; then
条件成 的命令 ( 可以有多个命令 )
else
条件不成 的命令 ( 可以有多个命令 )
fi
条件判断:可以有数字判断、字符串判断、⽂件判断等
三、数字判断
1 、格式
-eq equal ,等于,一般用于 [ $? -eq 0 ] ,也就是判断上条命令返回值等于 0 ,直接数字 -eq
字也可以 equals
-ne not equal ,不等于,一般用于 [ $? -ne 0 ] ,判断上条命令返回值不等于 0
-gt greater than ,大于
-ge greater or equal ,大于或等于
-lt less than ,小于
-le less or equal ,小于或等于
2 、应用示例
[root@localhost test] # test 2 -eq 2 # test shell 环境中,测试条件表达式的命令工具
[root@localhost test] # echo $?
0
[root@localhost test] # test 3 -eq 2 # 测试 3 等于 2
[root@localhost test] # echo $?
1 # 返回值为 1 ,说明测试的 3 等于 2 这条命令不成立
[root@localhost test] # [ 2 -eq 2 ] # 编程中习惯使 [ ] 中括号
[root@localhost test] # echo $?
0
[root@localhost test] # [ 3 -eq 2 ]
[root@localhost test] # echo $?
1
3 、创建简单的数字判断脚本
[root@localhost test] # vim if.sh
#!/bin/bash
num1 = 3 # 给定变量 num1
num2 = 3 # 给定变量 num2
if [ $num1 -eq $num2 ];then # 判断 num1 变量是否等于 num2
echo " $num1 equal $num2 " # 如果等于,那么执行命令, echo 输出
echo "in if"
fi
:wq
[root@localhost test] # sh ./if.sh
3 equal 3
in if
4 、创建检测网络是否畅通的脚本
[root@localhost test] # vim ping.sh
#!/bin/bash
read -p " 请输 要测试的 :" web # read :命令行内输入 web 的变量值
ping -c 3 $web &> /dev/null # ping -c 3 ,连接某个网站三次
if [ $? -eq 0 ];then # 如果 ping 命令执行成功,那么
echo " 此时 络畅通! " # 输出 此时网络畅通
else # 否则
echo " 法访问,请检查 址是否输 正确或检查相关的 络配置! " # 输出 无法访 问...”
fi # if 语句的结尾
:wq
[root@localhost test] # sh ./ping.sh
请输 要测试的 :www.baidu.com
此时 络畅通!
四、字符串判断
1 、格式
[ 字符串 1 == 字符串 2 ] 字符串内容相同
[ 字符串 1 != 字符串 2 ] 字符串内容不同
[ -z 字符串 ]       字符串内容为空
[ -n 字符串 ]       字符串内容不为空
[root@localhost test] # [ aaa == aaa ] # aaa 字符串等于 aaa
[root@localhost test] # echo $?
0 # 命令返回值为 0 ,说明 aaa==aaa
[root@localhost test] # [ aaa == bbb ] # aaa 字符串等于 bbb
[root@localhost test] # echo $?
1 # 命令返回值为非 0 ,说明 aaa 不等于 bbb
[root@localhost test] # [ -z aaa ] # aaa 字符串为空字符串
[root@localhost test] # echo $?
1 # 命令返回值为非 0 ,说明 aaa 字符串不为空
[root@localhost test] # [ -z ] # 直接引用空字符串
[root@localhost test] # echo $?
0 # 命令返回值为 0 ,说明上条判断命令为空字符串
[root@localhost test] # [ -n aaa ] # aaa 为非空字符串
[root@localhost test] # echo $?
0 # 命令返回值为 0 ,说明 aaa 为非空字符串
3 、案例
1 )创建简单的字符串判断脚本
[root@localhost test] # vim zifu.sh
#!/bin/bash
read -p " 请输 账号 :" name
if [ " $name " == "admin" ];then # 字符串判断需要加双引号
echo " 欢迎您, $name !"
else
echo " 系统未查询到此账号,请您重新输 "
fi
:wq
[root@localhost test] # sh ./zifu.sh
请输 账号 :admin
欢迎您, admin!
[root@localhost test] # sh ./zifu.sh
请输 账号 :ads
系统未查询到此账号,请您重新输
2 )创建 rpm 查询软件是否安装的脚本
[root@localhost test] # vim rpm.sh
#!/bin/bash
read -p " 请输 你要检测的 rpm :" rpmname # 命令行输入 rpmname 变量值
result = `rpm -qa $rpmname ` # 设置 result 变量为 `rpm -qa $rpmname` 命令
if [ -z " $result " ];then # 判断 result 变量内的命令执行后的值是否为空
echo " ${rpmname} is not find!" # 如果为空则输出这条
else
echo " ${rpmname} is find!" # 否则输出这条
fi
:wq
[root@localhost test] # sh ./rpm.sh
请输 你要检测的 rpm :nginx
nginx is not find !
[root@localhost test] # sh ./rpm.sh
请输 你要检测的 rpm :lrzsz
lrzsz is find !
五、文件、目录、权限的判断
示例
[root@localhost test] # [ -e "/etc/passwd" ] # 判断 /etc/passwd 文件是否存在
[root@localhost test] # echo $?
0
[root@localhost test] # [ -e "/etc/haha" ] # 判断 /etc/haha 文件是否存在
[root@localhost test] # echo $?
1
[root@localhost test] # [ -f "/etc" ] # 判断 /etc 是否为普通文件
[root@localhost test] # echo $?
1
[root@localhost test] # [ -x "/bin/bash" ] # 判断 /bin/bash 是否可执行
[root@localhost test] # echo $?
0
案例
[root@localhost test] # vim install_nginx.sh
#!/bin/bash
if [ -e "/usr/local/nginx" ];then # -e :判断 nginx 软件目录是否存在
echo "nginx is install!" # 存在则输出一条 nginx 已安装的提示信息
exit 1 # 输出完已安装信息则退出脚本
else # nginx 软件目录不存在,则执行如下命令
yum -y install gcc gcc-c ++ make pcre-devel openssl-devel wget
cd /usr/local/src/
wget 'http://nginx.org/download/nginx-1.22.1.tar.gz'
tar xf nginx-1.22.1.tar.gz
cd nginx-1.22.1
./configure --prefix = /usr/local/nginx
make -j 4 &&make install
ln -s /usr/local/nginx/sbin/nginx /usr/bin/
/usr/local/nginx/sbin/nginx
fi
:wq
[root@localhost test] # sh ./install_nginx.sh
六、与或判断
判断多个条件
多个条件其中一个成立,或
多个条件都要成立,与
或运算判断: ||
或,两个条件满足其一即可,还有 -o
与运算判断: && 与,两个条件都得满足才行,还有 -a
1 、或运算判断
[root@localhost test] # vim huo.sh
#!/bin/bash
read -p " 请输 字符串 :" name
if [ " $name " == "haha" ]||[ " $name " == "hehe" ];then # 这两个条件需满足其
一,也可使 [ "$name" =="haha" -o "$name" == "hehe" ]
echo " $name is my want"
else
echo "in else"
fi
:wq
[root@localhost test] # sh ./huo.sh
请输 字符串 :haha
haha is my want
[root@localhost test] # sh ./huo.sh
请输 字符串 :hehe
hehe is my want
[root@localhost test] # sh ./huo.sh
请输 字符串 :lala
in else
2 、与运算判断
[root@localhost test] # vim yu.sh
#!/bin/bash
read -p " 请输 ⼊⼀ 个数值 :" age
if [ $age -gt 30 ]&&[ $age -lt 80 ];then # 这两个条件都得满足,大于 30 且小于
80 ,可使用 [ $age -gt 30 -a $age -lt 80 ]
echo "age>30 and age<80"
echo "working"
else
echo "in else"
fi
:wq
[root@localhost test] # sh ./yu.sh
请输 ⼊⼀ 个数值 :60
age>30 and age<80
working
[root@localhost test] # sh ./yu.sh
请输 ⼊⼀ 个数值 :90
in else
3 、混合判断
[root@localhost test] # vim hun.sh
#!/bin/bash
read -p " 请输 ⼊⼀ 个数值 :" age
if [ $age -gt 2 ]&&[ $age -lt 10 ]||[ $age -eq 100 ];then # 先做 || 前面的与判
断,再进行或判断,可使 [ $age -gt 2 -a $age -lt 10 -o $age -eq 100 ]
echo "age is>2 and age is <10 or age ==100 "
else
echo "in else"
fi
:wq
[root@localhost test] # sh ./hun.sh
请输 ⼊⼀ 个数值 :7
age is>2 and age is <10 or age == 100
[root@localhost test] # sh ./hun.sh
请输 ⼊⼀ 个数值 :100
age is>2 and age is <10 or age == 100
[root@localhost test] # sh ./hun.sh
请输 ⼊⼀ 个数值 :30
in else
七、多重判断语法 elif
1 if 多分支语句结构
if 条件 1; then
# 命令,条件 1
elif 条件 2;then
# 命令,条件 1 不成 ,条件 2
elif 条件 3;then
# 命令,条件 1 不成 ,条件 2 不成 ,条件 3
else
# 命令 ,以上条件都不成
fi
2 、案例
[root@localhost test] # vim fs.sh
#!/bin/bash
# 分数等级评定
read -p " 请输 您的分数( 0-100 :" fs
if [ $fs -ge 0 -a $fs -lt 60 ];then
echo " $fs 分,不及格! "
elif [ $fs -ge 60 -a $fs -lt 70 ];then
echo " $fs 分,及格! "
elif [ $fs -ge 70 -a $fs -lt 85 ];then
echo " $fs 分,良好! "
elif [ $fs -ge 85 -a $fs -le 100 ];then
echo " $fs 分,优秀! "
else
echo " 您输 的分数有误! "
fi
:wq
[root@localhost test] # sh ./fs.sh
请输 您的分数( 0-100 :20
20 分,不及格!
[root@localhost test] # sh ./fs.sh
请输 您的分数( 0-100 :85
85 分,优秀!
[root@localhost test] # sh ./fs.sh
请输 您的分数( 0-100 :70
70 分,良好!
[root@localhost test] # sh ./fs.sh
请输 您的分数( 0-100 :123
您输 的分数有误!
八、多重判断的 case 语句
1 case 语句概述
case 语句是多分支选择语句
使用 case 语句改写 if 多分支可以使脚本结构更加清晰、层次分明。针对变量的不同取值,执行不同
的命令序列, case 还支持正则。
2 case 语句的结构
case $ 量名称 in
模式 1)
命令序列 1
;;
模式 2)
命令序列 2
;;
*)
认命令序列
esac
3 、示例
提示用户输入一个字符,判断该字符是字母、数字或者其他字符的脚本
#!/bin/bash
# 击键类型识别
read -p " 请输 ⼊⼀ 个字符,并按 Enter 键确认 :" key
case $key in
[a-z]|[A-Z]) # a z A Z ,当变量输入为字母则执行下面的 echo 命令
echo " 您输 的是 个 字 "
;;
[0-9]) # 0 9 ,当变量输入为数字则执行下面的 echo 的命令
echo " 您输 的是 个 数字 "
;;
*) # 若变量输入为空格等其他符号字符,则执行下
面的 echo 命令
echo " 您输 的是 空格、功能键或其他控制字符 "
;;
esac
:wq
[root@localhost test] # sh ./hitkey.sh
请输 ⼊⼀ 个字符,并按 Enter 键确认 :5
您输 的是 个 数字
[root@localhost test] # sh ./hitkey.sh
请输 ⼊⼀ 个字符,并按 Enter 键确认 :b
您输 的是 个 字
[root@localhost test] # sh ./hitkey.sh
请输 ⼊⼀ 个字符,并按 Enter 键确认 :P
您输 的是 个 字
[root@localhost test] # sh ./hitkey.sh
请输 ⼊⼀ 个字符,并按 Enter 键确认 :!
您输 的是 空格、功能键或其他控制字符
4 、案例
输入分数变量,然后判定等级
[root@localhost test] # vim fscase.sh
#!/bin/bash
# 使 case 语句编写分数等级评定脚本
read -p " 请输 您的分数( 0-100 :" fs
case $fs in
[0-9]|[0-5][0-9]) # 0 9 59 以内的两位数
echo " $fs 分,不及格! "
;;
6 [0-9]) # 6 开头的两位数,若 $fs 输入为 0 ,则判定为 60 ,即执行下面的 echo 命令
echo " $fs 分,及格! "
;;
7 [0-9]|8[0-5]) # 7 开头的两位数或以 8 开头的两位数
echo " $fs 分,良好! "
;;
8 [6-9]|9[0-9]|100) # 8 开头的两位数,第二位最少为 6 ,也就是最小是 86 | 9
开头的两位数 | 100
echo " $fs 分,优秀! "
;;
*) # 输入不在上述规则内的其他字符,则 echo 如下命令
echo " 您输 的分数有误! "
esac
:wq
[root@localhost test] # sh ./fscase.sh
请输 您的分数( 0-100 :5
5 分,不及格!
[root@localhost test] # sh ./fscase.sh
请输 您的分数( 0-100 :58
58 分,不及格!
[root@localhost test] # sh ./fscase.sh
请输 您的分数( 0-100 :69
69 分,及格!
[root@localhost test] # sh ./fscase.sh
请输 您的分数( 0-100 :70
70 分,良好!
[root@localhost test] # sh ./fscase.sh
请输 您的分数( 0-100 :89
89 分,优秀!
[root@localhost test] # sh ./fscase.sh
请输 您的分数( 0-100 :100
100 分,优秀!
[root@localhost test] # sh ./fscase.sh
请输 您的分数( 0-100 :110
您输 的分数有误!
shell脚本循环语法
一、 for 循环
1 、作用
读取不同的变量值,以逐个执行同一组命令
2 、结构
for 变量名 in 取值列表 ( 范围 )
do
命令序列
done
取值列表:数字范围、字符串、多个字符串、提前设定好的变量等
for 默认以所有的空白字符进行分隔 : tab 、空格、回车,去循环处理
分隔成几段就循环几次
3 、示例
1 )分隔值循环
[root@localhost test] # vim quzhi.sh
#!/bin/bash
for home in 北京 上海 州 深圳 # home 变量在北京、上海、广州、深圳这四个地名中间循环一
do
echo " $home 是个好地 "
done
:wq
[root@localhost test] # bash quzhi.sh
北京 是个好地
上海 是个好地
州 是个好地
深圳 是个好地
2 )在命令结果中循环
[root@localhost test] # vim 1.sh
#!/bin/bash
x = 1
for user in $(awk -F':' '{print $1 }' /etc/passwd) # /etc/passwd 文件中以用
户名作为循环
do
echo " $x 户名称为 : $user "
let x = x + 1
done
echo " 该系统有 $(( $x -1)) "
:wq
[root@localhost test] # bash 1.sh
1 户名称为 : root
... 省略部分内容
45 户名称为 : yunjisuan
46 户名称为 : apache
47 户名称为 : nginx
该系统有 47
3 )检测某个网段的存活主机
[root@localhost test] # vim ping.sh
#!/bin/bash
for IP in $(echo 192.168.33.{100..120}) # 192.168.33 网段的 100 120 的主机,在此
循环
do
ping -c 2 -i 0 .1 $IP &> /dev/null
if [ $? -eq 0 ];then
echo "Host $IP is up."
fi
done
:wq
[root@localhost test] # bash ping.sh
Host 192 .168.100.100 is up.
Host 192 .168.100.101 is up.
4 )判断包是否已安装
[root@localhost test] # vim 2.sh
#!/bin/bash
for softpack in wget gcc pcre pcre-devel zlib zlib-devel;do
soft_result = $(rpm -qa $softpack )
if [ -z " $soft_result " ];then
yum install -y $softpack
else
echo " $softpack is installed"
fi
done
[root@localhost test] # bash 2.sh
wget is installed
gcc is installed
pcre is installed
pcre-devel is installed
zlib is installed
zlib-devel is installed
二、 while 循环
1 、作用
重复测试某个条件,只要条件成立则反复执行
2 、结构
while 条件测试操作
do
命令序列
done
3 while for 区别
while 循环也有条件判断,当条件成立的时候,会循环执行。当条件不成立退出
if 判断当条件成立时,会执行一次,然后退出。当条件不成立时直接退出
4 、示例
1 )批量添加用户
创建时交互输入用户前缀、创建用户个数、初始密码、过期时间 ( 可选设置 ) ,用户首次登陆强制要
求修改密码
[root@localhost test] # vim useradd.sh # 批量创建 户脚本
#!/bin/bash
read -p " 请输 创建 户的名称前缀 :" QZ
read -p " 请输 创建 户的个数 :" NUM
read -p " 请输 ⼊⽤ 户的初始密码 :" PS
i = 1
while [ $i -le $NUM ]
do
useradd $QZ$i
echo " $PS " |passwd --stdin $QZ$i &> /dev/null
chage -d 0 $QZ$i
let i ++
done
:wq
[root@localhost test] # bash useradd.sh
请输 创建 户的名称前缀 :admin
请输 创建 户的个数 :5
请输 ⼊⽤ 户的初始密码 :123456
[root@localhost test] # tail /etc/passwd
[root@localhost test] # vim userdel.sh # 批量删除 户脚本
#!/bin/bash
read -p " 请输 要删除 户的前缀 :" QZ
read -p " 请输 要删除 户的个数 :" NUM
i = 1
while [ $i -le $NUM ]
do
userdel -r $QZ$i
let i ++
done
:wq
[root@localhost test] # bash userdel.sh
请输 要删除 户的前缀 :admin
请输 要删除 户的个数 :5
三、循环的 break continue
break 直接结束循环,循环立即退出
continue 可以用来跳过一次循环,跳过后循环继续,直到循环停止
1 、示例
[root@localhost test] # vim test.sh
#!/bin/bash
for line in 北京 上海 州 深圳
do
echo $line
if [ " $line " == " 上海 " ];then $ 循环到上海 即退出
break
fi
done
:wq
[root@localhost test] # bash test.sh
北京
上海
[root@localhost test] # vim test.sh
#!/bin/bash
for line in 北京 上海 州 深圳
do
if [ " $line " == " 上海 " ];then
continue
fi
echo $line
done
:wq
[root@localhost test] # bash test.sh
北京
深圳
三、九九乘法表
[root@localhost test] # vim 99.sh
#!/bin/bash
# 九九乘法表
for i in {1..9};do
for j in {1..9};do
echo -n " $j * $i = $(( $i * $j )) "
if [ $j == $i ];then
echo -e '\n'
break
fi
done
done
:wq
[root@localhost test] # bash 99.sh
1 *1 = 1
1 *2 = 2 2 *2 = 4
1 *3 = 3 2 *3 = 6 3 *3 = 9
1 *4 = 4 2 *4 = 8 3 *4 = 12 4 *4 = 16
1 *5 = 5 2 *5 = 10 3 *5 = 15 4 *5 = 20 5 *5 = 25
1 *6 = 6 2 *6 = 12 3 *6 = 18 4 *6 = 24 5 *6 = 30 6 *6 = 36
1 *7 = 7 2 *7 = 14 3 *7 = 21 4 *7 = 28 5 *7 = 35 6 *7 = 42 7 *7 = 49
1 *8 = 8 2 *8 = 16 3 *8 = 24 4 *8 = 32 5 *8 = 40 6 *8 = 48 7 *8 = 56 8 *8 = 64
1 *9 = 9 2 *9 = 18 3 *9 = 27 4 *9 = 36 5 *9 = 45 6 *9 = 54 7 *9 = 63 8 *9 = 72 9 *9 = 81
[root@localhost test] #
[root@localhost test] # vim 99-2.sh
#!/bin/bash
# 九九乘法表
i = 1
while [ $i -le 9 ];do
j = 1
while [ $j -le 9 ];do
echo -n " $j * $i = $(( $i * $j )) "
if [ $j -eq $i ];then
echo -e '\n'
break
fi
let j ++
done
let i ++
done
:wq
[root@localhost test] # bash 99-2.sh
1 *1 = 1
1 *2 = 2 2 *2 = 4
1 *3 = 3 2 *3 = 6 3 *3 = 9
1 *4 = 4 2 *4 = 8 3 *4 = 12 4 *4 = 16
1 *5 = 5 2 *5 = 10 3 *5 = 15 4 *5 = 20 5 *5 = 25
1 *6 = 6 2 *6 = 12 3 *6 = 18 4 *6 = 24 5 *6 = 30 6 *6 = 36
1 *7 = 7 2 *7 = 14 3 *7 = 21 4 *7 = 28 5 *7 = 35 6 *7 = 42 7 *7 = 49
1 *8 = 8 2 *8 = 16 3 *8 = 24 4 *8 = 32 5 *8 = 40 6 *8 = 48 7 *8 = 56 8 *8 = 64
1 *9 = 9 2 *9 = 18 3 *9 = 27 4 *9 = 36 5 *9 = 45 6 *9 = 54 7 *9 = 63 8 *9 = 72 9 *9 = 81

sed流式编辑器

一、概述
sed 是文本处理工具,读取文本内容,根据指定条件进行处理,可实现
增删改查的功能。 sed 依赖于正则表达式。
二、编辑命令格式
'/ 地址 1 ,地址 2/ 操作 ( 参数 )'
示例
1 )准备文件
[root@localhost test] # vim test.txt
gd
god
good
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
IP 173 .16.16.1
pay $1 80
:wq
2 p 打印
[root@localhost test] # sed -n '12p' test.txt #
输出第 12 内容
HELLO
[root@localhost test] # sed -n '3,5p' test.txt # 输出
3~5 内容
good
goood
gooood
[root@localhost test] # sed -n 'p;n' test.txt #
输出奇数
gd
good
gooood
glad
abcdEfg
60115127Z
010 -66668888
IP 192 .168.1.108
pay $1 80
[root@localhost test] # sed -n 'n;p' test.txt #
输出偶数
god
goood
gold
gaad
food
HELLO
0666 -5666888
IP 173 .16.16.1
[root@localhost test] # sed -n '1,6{p;n}' test.txt # 输出 1~6
之间的奇数 (第 1,3,5
gd
good
gooood
[root@localhost test] # sed -n '/H/p' test.txt # 输出
包含字 H
HELLO
[root@localhost test] # sed -n '/[A-Z]/p' test.txt # 输出所有
包含 写字
abcdEfg
60115127Z
HELLO
IP 192 .168.1.108
IP 173 .16.16.1
[root@localhost test] # sed -n '$p' test.txt #
输出最后 ⼀⾏
pay $1 80
3 d 删除
[root@localhost test] # sed '16d' test.txt # 删除第十六
gd
god
good
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
pay $1 80
[root@localhost test] # cat -n test.txt
1 gd
2 god
3 good
4 goood
5 gooood
6
7 gold
8 glad
9
10 gaad
11 abcdEfg
12 food
13
14 60115127Z
15 HELLO
16 010 -66668888
17 0666 -5666888
18 IP 192 .168.1.108
19 IP 173 .16.16.1
20 pay $1 80
[root@localhost test] # sed -i '/^$/d' test.txt # 删除
空行, ^$ :表示空行
[root@localhost test] # cat -n test.txt
1 gd
2 god
3 good
4 goood
5 gooood
6 gold
7 glad
8 gaad
9 abcdEfg
10 food
11 60115127Z
12 HELLO
13 010 -66668888
14 0666 -5666888
15 IP 192 .168.1.108
16 IP 173 .16.16.1
17 pay $1 80
[root@localhost test] # sed -e '1d' -e '3d' test.txt #
删除第 1 和第 3
god
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
IP 173 .16.16.1
pay $1 80
[root@localhost test] # sed -e '1d;3d' test.txt
# 同样,删除第 1 和第 3
god
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
IP 173 .16.16.1
pay $1 80
4 s 替换字符串
[root@localhost test] # sed 's/o/O/g' test.txt # 将所
o 替换为 O g 表示若同 ⼀⾏ 有多个 o ,全部替换,若不加 g ,则只
替换每 的第 o
gd
gOd
gOOd
gOOOd
gOOOOd
gOld
glad
gaad
abcdEfg
fOOd
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
IP 173 .16.16.1
pay $1 80
[root@localhost test] # sed '/^IP/ s/^/#/' test.txt #
IP 开头的 ⾏⾸ 加上
#
gd
god
good
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
#IP 192.168.1.108
#IP 173.16.16.1
pay $1 80
[root@localhost test] # sed 's/$/EOF/' test.txt # 在每
⾏⾏ 尾插 字符串 EOF
gdEOF
godEOF
goodEOF
gooodEOF
goooodEOF
goldEOF
gladEOF
gaadEOF
abcdEfgEOF
foodEOF
60115127ZEOF
HELLOEOF
010 -66668888EOF
0666 -5666888EOF
IP 192 .168.1.108EOF
IP 173 .16.16.1EOF
pay $1 80EOF
[root@localhost test] # sed '20,25
s@/sbin/nologin@/bin/bash@' /etc/passwd
# /etc/passwd 20~25 /sbin/nologin 替换为 /bin/bash 。如 果⽤ s/// 的形式,将会多次使 转义符 \ ,我们可以使 其他符号,如 @ 分隔
5 c 替换整行
[root@localhost test] # sed '2cAAAAAAA' test.txt #
将第 2 替换为 AAAAA
gd
AAAAAAA
good
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
IP 173 .16.16.1
pay $1 80
[root@localhost test] # sed '5,$ cAAAAA\nBBBBB' test.txt
# 把第 5 ⾏⾄ 最后 ⼀⾏ 的内容替换为两 AAAAA BBBBB \n 为换
gd
god
good
goood
AAAAA
BBBBB
6 r 追加指定文件到行后
[root@localhost test] # sed '5r /etc/hostname' test.txt #
/etc/hostname 件内容在第 5
gd
god
good
goood
gooood
localhost.localdomain
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
IP 173 .16.16.1
pay $1 80
7 a 追加指定内容到行后
[root@localhost test] # sed '2aCCCCCCCCC' test.txt #
在第二行后追加 9 C
gd
god
CCCCCCCCC
good
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
IP 173 .16.16.1
pay $1 80
[root@localhost test] # sed '/[0-9]/a=====' test.txt #
在所有带数字的 下追
====
gd
god
good
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
=====
HELLO
010 -66668888
=====
0666 -5666888
=====
IP 192 .168.1.108
=====
IP 173 .16.16.1
=====
pay $1 80
=====
8 i 追加指定内容到行前
[root@localhost test] # sed '2iCCCCC' test.txt # 在第
二行之前追加 5 C
gd
CCCCC
god
good
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
IP 173 .16.16.1
pay $1 80
9 w 另存为
[root@localhost test] # sed '15,16w 123.txt' test.txt
# 15~16 内容另存到 123.txt 件中
gd
god
good
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
IP 173 .16.16.1
pay $1 80
[root@localhost test] # cat 123.txt
IP 192 .168.1.108
IP 173 .16.16.1
10 H G 复制剪切粘贴
H :复制到剪贴板
G :将剪贴板中的内容追加到指定行后
[root@localhost test] # sed '/IP/ {H;d};$G' test.txt
# 将包含字 IP 剪切到最后 ⼀⾏
gd
god
good
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
pay $1 80
IP 192 .168.1.108
IP 173 .16.16.1
[root@localhost test] # sed '1,5H;15,16G' test.txt #
1~5 内容复制到 15 16
gd
god
good
goood
gooood
gold
glad
gaad
abcdEfg
food
60115127Z
HELLO
010 -66668888
0666 -5666888
IP 192 .168.1.108
gd
god
good
goood
gooood
IP 173 .16.16.1
gd
god
good
goood
gooood
pay $1 80
三、 sed 命令引用变量
1. sed 命令使用单引号的情况下,可以使用 '"$var"' 引用(单引号,然后 双引号,变量):
sed -i '2s/node_base/'" $i "'/' /etc/libvirt/qemu/ $i .xml
1. sed 命令中使用双引号的情况下,直接 shell command 或者 $(shell command) 引用命令执行。
sed -i "2s/node_base/ $i /" /etc/libvirt/qemu/ $i .xml
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值