Shell循环结构

297 阅读3分钟

shell循环结构

echo命令

echo -n   表示不换行输出
echo -e   表示输出转义符
常用的转义符
选项作用
\n输出换行
\r光标移至行首,并且不换行
\s当前shell的名称,如bash
\t插入Tab键
\f换行,但光标仍停留在原处
\ \表示插入""本身
\b表示退格 不显示前一个字符
\c抑制更多的输出或不换行
[root@localhost]#echo -e "12345\b678"
##退格删除前面的字符
1234678
[root@localhost]#echo -e "12345\b\b678"
123678
[root@localhost]#echo -e "12345\b\b\b678"
12678
[root@localhost#echo -e "12345\b\b\b\b678"
16785
###注意退格键和末尾的字符相关,超过末尾的字符数量 会出bug 了解即可
[root@localhost#echo -e "12345678\c"
12345678
[root@localhost]#echo -e "1234\c5678"
1234
[root@localhost]#
###\c 注意 使用在数字中间会把后面内容删除

$RANDOM 取值范围:0-32767

[root@test1 ~]# echo $[$RANDOM%50]
37
[root@test1 ~]# echo $[$RANDOM%20]
11

date命令

用处:date查看当前系统时间

命令含义
-d你描述的日期,显示指定字符串所描述的时间,而非当前时间
%F完整日期格式,等价于 %Y-%m-%d
%T时间(24小时制)(hh:mm:ss)
[root@localhost ~]# date -d '-1 day' +%F 
2022-06-13

[root@localhost ~]# date  +%F 
2022-06-13
[root@localhost ~]# date -d '1 day ' +%F-%T
2021-08-20-23:28:42
[root@localhost mnt]# date -d "-3 day"      前三天
20210818日 星期三 11:30:15 CST
[root@localhost mnt]# date -d "+3 day"  后三天
20210818日 星期三 11:30:15 CST
[root@localhost data]#date -d '1 day ' +%F'     '%T
2021-10-22     00:45:37
日历
[root@localhost data]#cal 2021
#查看日历

[root@localhost data]#cal 9 1752
      九月 1752     
日 一 二 三 四 五 六
       1  2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

循环含义

将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件

重复运行次数

  • 循环次数事先已知
  • 循环次数事先未知

常见的循环的命令:for, while, until image-20211210001505637.png

for

执行机制:遍历

执行机制:
依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环
结束
如果省略 [in WORDS ... ] ,此时使用位置参数变量 in "$@"

 for (( 表达式1; 表达式2; 表达式3 )); do 命令; done

image-20211210102157228.png 例子:

批量改后缀名:
DIR=/data/test
cd $DIR || {  echo 无法进入 $DIR;exit 1; }
for FILE in * 
do
 PRE=`echo $FILE|grep -Eo ".*\."`
    mv $FILE ${PRE}bak
done  


#!/bin/bash
cd /data
for file in *
do
name=`echo $file |cut -d "." -f1`
mv $file   ${name}.bak
done

while 和 until

相对于for,需要知道循环次数

我们只知道停止条件,不知道次数,就需要使用while

直到达到条件

while
当命令判断为假时停止

until
当命令判断为真时停止

双重循环及跳出循环

  • break跳出单个循环后面加数字2则代表跳出两层循环
  • continue终止某次循环中的命令,但是不会完全终止命令

示例:

[root@localhost ~]#cat continue.sh 
#本层循环
#!/bin/bash
for i in {1..10}
do
if [ $i -eq 5 ]
then continue 
fi
echo i=$i
done

[root@localhost ~]#cat break.sh 
#本层循环
#!/bin/bash
for i in {1..10}
do
if [ $i -eq 5 ]
then break
fi
echo i=$i
done


[root@localhost ~]#cat continue.sh 
#本层循环
#!/bin/bash
for i in {1..10}
do
if [ $i -eq 5 ]
then continue 2
fi
echo i=$i
done


[root@localhost ~]#cat break.sh 
#本层循环
#!/bin/bash
for i in {1..10}
do
if [ $i -eq 5 ]
then break 2
fi
echo i=$i
done
#select  菜单选择
[root@localhost ~]#select menu in 配置网卡 配置yum源;do echo $menu;done
1) 配置网卡
2) 配置yum源
#? 1
配置网卡
#? 2
配置yum源
#? 
[root@localhost ~]#PS3="请选择功能(1-2):";select menu in 配置网卡 配置yum源;do echo $menu;done
1) 配置网卡
2) 配置yum源
请选择功能(1-2):1
配置网卡
请选择功能(1-2):2
配置yum源
请选择功能(1-2):

菜单

[root@localhost data]#help select
select: select NAME [in 词语 ... ;] do 命令; done
    从列表中选取词并且执行命令。
    
    WORDS 变量被展开,生成一个词的列表。展开的词集合被打印
    在标准错误输出设备上,每个以一个数字做前缀。如果没有 `in WORDS'
    则假定使用`in "$@"'。PS3提示符会被显示并且从标准输入读入一行
    如果该行由被显示的词对应的数字组成,则 NAME 变量被设定为相应
    的词。如果行为空,则 WORDS 变量和提示符被重新显示。如果读取了
    文件结束符,则命令完成。读入任何其他的值会导致 NAME 变量被设定
    为空。读入的行被存放在变量 REPLY 中。COMMANDS 命令在每次选择
    之后执行直到执行一个 break 命令。
    
    退出状态:
    返回最后一个执行的命令的状态。


一定要使用$REPLY

[root@localhost data]#select menu in 配置网卡 配置yum源;do echo $REPLY;done
#与for相似
[root@localhost data]#select menu in 配置网卡 配置yum源;do echo $menu;done
PS3="请选择功能(1-2)";select menu in 配置网卡 配置yum源;do echo $menu;done
PS3="请选择功能(1-2):";select menu in 配置网卡 配置yum源;do echo $menu;done

ps2=

[root@localhost ~]#select menu in 配置网卡 配置yum源;do echo $REPLY;done
1) 配置网卡
2) 配置yum源
#? 1
1
#? 2
2
#? ^C

[root@localhost ~]#select menu in 配置网卡 配置yum源;do echo $menu;done
1) 配置网卡
2) 配置yum源
#? 1
配置网卡
#? 2
配置yum源


PS1 提示符
PS2 多行重定向
PS3 菜单选择


#!/bin/bash
sum=0
PS3="请输入(1-6):"
MENU="
宫保鸡丁
酸菜鱼
鱼香肉丝
佛跳墙
水煮肉片
点菜结束
"

select menu in $MENU
do
case $REPLY in
1)
echo $menu 价格是20
let sum+=20
;;
2)
echo $menu 价格是60
let sum+=60
;;


3)
echo $menu 价格是25
let sum+=25
;;

4)
echo $menu 价格是150
let sum+=150
;;

5)
echo $menu 价格是60
let sum+=60
;;

6)
echo "点菜结束"
break
;;

*)
echo "点菜错误,请重新选择"
;;

esac
done

echo "总价是$sum"