4. Shell 循环语句
重点:
条件测试。
read。
Shell 环境配置。
case。
for。
find。
xargs。
gzip,bzip2,xz。
tar。
sed。
1)循环
1.1)循环执行介绍

将某代码段重复运行多次,通常有 进入循环的条件 和 退出循环的条件。
重复运行次数
循环次数 事先已知
循环次数 事先未知
常见的循环的命令
for
while
until
逻辑:程序先进入语句判断,如真则执行循环语句,然后再进行语句判断,直到语句判断失败才退出。

1.2)循环 For 语句
type for

for NAME [ in WORDS ... ] ; do CMD1 ; done
-- 方式 1
for 变量名 in 列表; do
循环体
done
-- 方式 2
for 变量名 in 列表
do
循环体
done
执行机制
依次将列表中的元素赋值给 "变量名";每次赋值后即执行一次循环体;直到列表中的元素耗尽,循环结束。
如果省略 [ in WORDS ... ],此时使用位置参数变量 in "$@"。
[ 举例 1 ]
使用 for 循环来遍历脚本运行时传递的参数列表。
-- 编写脚本
vim for.sh
#!/bin/bash
for i; do
echo i=$i
done
-- 执行脚本
bash for.sh a b c d e

命令解析
bash -x for.sh a b c d e

[ 举例 2 ]
for i in a b c d e;
do
echo i=$i;
done

总结:
第一个命令是一个脚本文件,可以接受 标准输入参数 作为循环变量。
第二个命令是在终端中直接运行的一行命令,它使用 硬编码的字符串列表 作为循环变量。
[ 举例 3 ]
使用 for 循环来遍历一个 数字范围 并打印出结果的命令。
for i in {1..10};do
echo i=$i;
done

[ 举例 4 ]
使用 for 循环来 遍历当前目录下所有以 ".sh" 结尾的文件,并打印出这些文件的名称 bash /root/$i
for i in *.sh;do
echo "bash /root/$i";
done

[ 举例 5 ]
计算从 1 到 100 之间的所有整数之和,并打印出结果。
sum=0:在脚本中初始化一个变量 sum,用于存储累加的和。
for i in {1..100}; do:这部分是循环的头部,使用 for 循环遍历从 1 到 100 的整数范围。${1..100} 是 Bash 的一个特性,它展开成一个包含从 1 到 100 的整数序列的列表。
let sum+=i:在循环体内,这行命令将当前循环变量 i 的值加到变量 sum 上,实现了累加操作。
echo sum=$sum:这行命令在循环结束后打印出累加的和。${sum} 会被替换为变量 sum 的值,然后将结果打印出来。
#!/bin/bash
sum=0
for i in {1..100};do
let sum+=i
done
echo sum=$sum

[ 举例 6 ]
生成一个 带有彩色星号的矩阵图案,其中颜色通过 ANSI 转义码进行控制。
这个脚本 使用嵌套的循环生成一个 6x6 的矩阵,每个位置都填充了一个带有随机颜色的星号。脚本运行后,您会看到一个具有不同颜色星号的矩阵图案。

#!/bin/bash
# 负责 竖着打印 1 - 6 行
for j in {1..6};do
# 负责控制每行中的星号数
for i in {1..6};do
echo -e "\E[1;$[RANDOM%7+31]m*\E[0m\c"
done
echo
done

[ 举例 7 ]

#!/bin/bash
# 负责 竖着打印 1 - 6 行
for j in {1..6};do
# 负责控制每行中的星号数
for i in `seq $j`;do
echo -e "\E[5;1;$[RANDOM%7+31]m*\E[0m\c"
done
echo
done

[ 举例 8 ]

#!/bin/bash
for j in {1..9};do
for i in `seq $j`;do
echo -e "\E[5;1;$[RANDOM%7+31]m ${i}x${j}=$[i*j] \E[0m \t\c"
done
echo
done

1.3)循环 For 语句
语法 2
help for

语法逻辑
for (( exp1; exp2; exp3 )); do COMMANDS; done
for (( 控制变量初始化; 条件判断表达式; 控制变量的修正表达式 ))
do
循环体
done

使用 For 循环 语法 2

#!/bin/bash
for (( sum=0,i=1; i<=100; i++ )); do
let sum+=i
done
echo sum=$sum

使用 For 循环 语法 2
#!/bin/bash
for (( i=1;i<=9;i++ ));do
for (( j=1;j<=i;j++ ));do
echo -e "\E[5;1;$[RANDOM%7+31]m ${i}x${j}=$[i*j] \E[0m \t\c"
done
printf "\n"
done

1.4)循环 For 案例
范例 1 :批量创建用户和并设置随机密码。
[ 创建了 10 个用户,为每个用户生成随机密码,并将用户名和密码写入日志文件。 ]

vim user_for.sh
#!/bin/bash
for i in {1..10}; do
useradd user$i
PASS=`cat /dev/urandom | tr -dc '[:alnum:]' |head -c12`
echo $PASS | passwd --stdin user$i &> /dev/null
echo user$i: $PASS >> /root/user.log
echo "user$i is created"
done

Windows 10:截图功能快捷键
Win + Shift + S
范例 2 :将指定目录下的文件所有文件的后缀改名为 bak 后缀。

// 前置环境
mkdir -p /data/test && cd /data/test
touch {1..10}.txt
--
vim for_rename.sh
#!/bin/bash
DIR=/data/test
cd $DIR || { echo 无法进入 $DIR; exit 1; }
for FILE in * ;do
PRE=`echo $FILE | grep -Eo ".*\."`
mv $FILE ${PRE}bak
done
--
bash for_rename.sh

范例 3 :要求将目录 YYYY-MM-DD/ 中所有文件,移动到 YYYY-MM/DD/ 下
1. 创建 YYYY-MM-DD 格式的目录

--
1. 创建 YYYY-MM-DD 格式的目录
# 当前日期一年前 365 天到目前共 365 个目录
# 里面有 10 个文件 .log 后缀的文件
#!/bin/bash
PDIR=/data/test # 指定父目录路径
for i in {1..365}; do # 循环从 1 到 365
DIR=$(date -d "-$i day" +%F) # 根据当前日期倒推 i 天的日期格式
mkdir -pv $PDIR/$DIR # 创建子目录,-p 表示递归创建目录,-v 表示显示创建的目录
cd $PDIR/$DIR # 进入子目录
for j in {1..10}; do # 循环从 1 到 10
touch $RANDOM.log # 创建一个随机名称的日志文件
done
done

2. 将上面的目录移动到 YYYY-MM/DD/ 下

--
2. 将上面的目录移动到 YYYY-MM/DD/ 下
#!/bin/bash
DIR=/data/test # 指定目录路径
cd $DIR || { echo 无法进入 $DIR; exit 1; } # 切换到目标目录,如果失败则显示错误信息并退出
for subdir in *; do # 遍历目录下的子目录
YYYY_MM=$(echo $subdir | cut -d"-" -f1,2) # 提取子目录名的前两部分,即年月
DD=$(echo $subdir | cut -d"-" -f3) # 提取子目录名的第三部分,即日
[ -d $YYYY_MM/$DD ] || mkdir -p $YYYY_MM/$DD &> /dev/null # 如果目标日期子目录不存在,则创建
mv $subdir/* $YYYY_MM/$DD # 将子目录下的文件移动到目标日期子目录中
done
rm -rf $DIR/*-*-* # 删除原始子目录

范例 4 :扫描一个网段:10.0.59.0/24,判断此网段中主机在线状态,将在线的主机的IP打印出来。

vim for_host.sh
#!/bin/bash
NET=10.0.59
touch host_list.log
for ID in {1..254}; do
{
if ping -c1 -W1 $NET.$ID &> /dev/null; then
echo $NET.$ID is up | tee -a host_list.log
else
echo $NET.$ID is down
fi
} &
done
wait

1.5)练习题
[ 基于 For 循环实现 ]
1、判断 /var 目录下所有文件的类型
2、添加 10 个 用户 user1-user10,密码为 8 位随机字符。
3、/etc/rc.d/rc3.d 目录下分别有多个以 K 开头和以 S 开头的文件;分别读取每个文件,以 K 开头的输出为文件加 stop,以 S 开头的输出为文件名加start,如 K34filename stop S66filename start。
4、编写脚本,提示输入正整数 n 的值,计算 1+2+…+n 的总和。
5、计算 100 以内所有能被 3 整除的整数之和。
6、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态。
7、打印九九乘法表
8、在 /testdir 目录下创建10个 html 文件,文件名格式为数字N(从1到10)加随机8个字母,如:1AbCdeFgH.html。
9、打印等腰三角形
10、猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,只剩下一个桃子了。求第一天共摘了多少?
4. Shell 循环语句的更多相关文章
- Shell循环语句for、while、until
Shell循环语句for.while.until 一.条件测试 二.删除字符 三.循环语句 示例1 ...
- shell循环语句
所有的笔记只记录一些例子,根据例子解释一些出现的语法,不介绍具体的语法 2015-07-01 21:58:33 星期三 for循环 用例一用for循环在家目录下创建aaa1-aaa10,然后在aaa1 ...
- shell循环语句until
until 条件 do 执行命令 done until 循环与 while 循环在处理方式上刚好相反. 当条件成立的时候,停止循环.
- shell循环语句for
1.方式1 for i in {list[0]} {list[1]} .. do 执行命令 done 2.方式2(三要素循环) for (( 初始值; 判断值; 步长; )) do 执行命令 done
- shell 循环语句
1.while 2.for 3.until 4.select while #!/bin/bash # 显示一系列数字 count=1 while [ $count -le 6 ]; do echo $ ...
- shell循环语句while
格式1: while 条件 do 执行命令 done 格式2: while 条件;do 命令 done 例子: while [ 1 -eq 1 ];do echo "这一步需要先修改/dat ...
- shell 学习笔记9-while/until循环语句
一.while循环语句 1.循环语句 循环愈久就是重复执行一条指令或一组执行,知道条件不在满足时停止,shell循环语句包括,while.until.for.select语句 2.while循环 主要 ...
- shell编程系列18--文本处理三剑客之awk动作中的条件及if/while/do while/for循环语句
shell编程系列18--文本处理三剑客之awk动作中的条件及if/while/do while/for循环语句条件语句 if(条件表达式) 动作1 else if(条件表达式) 动作2 else 动 ...
- shell编程基础(二): shell脚本语法之分支语句和循环语句
一.分支语句 1.条件测试:test [ 命令test或[可以测试一个条件是否成立,如果测试结果为真,则该命令的Exit Status为0,如果测试结果为假,则命令的Exit Status为1(注意与 ...
- Shell脚本应用(for、while循环语句和case分支语句)
1.for:读取不同的变量值,逐个执行同一组命令,直到取值完毕退出,变量值以空格分隔 语法: for 变量值 in 取值列表 do 命令序列 done 2.while:重复测试某个条件,成立则执 ...
随机推荐
- java与es8实战之三:Java API Client有关的知识点串讲
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<java与es8实战>系 ...
- [编程基础] Python内置模块collections使用笔记
collections是Python标准库中的一个内置模块,它提供了一些额外的数据结构类型,用于增强Python基础类型如列表(list).元组(tuple)和字典(dict)等.以下是对collec ...
- 一文解锁vue3中hooks的使用姿势
vue3 中的 hooks 是什么? 简单来说如果你的函数中用到了诸如 ref,reactive,onMounted 等 vue 提供的 api 的话,那么它就是一个 hooks 函数,如果没用到它就 ...
- SQL查询中的小技巧:SELECT 1 和 LIMIT 1 替代 count(*)
前言 在写SQL查询时,常规做法是使用SELECT count(*)来统计符合条件的记录数. 然而,在某些情况下,我们只关心是否存在符合条件的记录,而不需要知道具体的记录数. 为了优化性能,可以改用使 ...
- 【Qt6】列表模型——便捷类型
前一篇水文中,老周演示了 QAbstractItemModel 抽象类的继承方法.其实,在 Qt 的库里面,QAbstractItemModel 类也派生了两个基类,能让开发者继承起来[稍稍]轻松一些 ...
- SpringBoot 后端配置 Https 教程
以阿里云为例子 1. 申请 SSL 证书 1. 注册域名 打开阿里云官网,搜索域名 点击域名注册,输入域名,点击搜索 选择心仪的域名,点击购买,打钱 进入域名控制台,进行实名认证 2. 申请 SSL ...
- Solution -「洛谷 P5610」「YunoOI 2013」大学
Description Link. 区间查 \(x\) 的倍数并除掉,区间查和. Solution 平衡树. 首先有个基本的想法就是按 \(a_{i}\) 开平衡树,即对于每个 \(a_{i}\) 都 ...
- 6.swagger完善:界面显示注释+多版本控制
周末,写点简单的水一下. 新版本的vs创建项目的时候可以选择自带一个swagger.然而这只是基本的swagger功能. 几个接口无所谓啦,随着接口越来越多,就这么丢给你,一时间也会懵逼,所以这篇文章 ...
- 算法打卡|Day2 数组part02
Day2 数组part02 今日任务:977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II 目录 Day2 数组part02 今日任务:977.有序数组的平方 ,209.长度最小的 ...
- stm32开发笔记
STM32F103C8T6单片机简介 标准库与HAL库区别 寄存器 寄存器众多,需要经常翻阅芯片手册,费时费力: 更大灵活性,可以随心所欲达到自己的目的: 深入理解单片机的运行原理,知其然更知其所以然 ...