Shell循环
回顾
上一章学习的结构化命令中的 if-then 和 case 语句,其中 if-then 语句是通过检查命令的执行结果或者表达式(文件比较、字符串比较、数值比较)的结果来控制脚本的执行流程。
在Shell脚本中,循环语句是一种重要的控制结构,用于多次执行同一段代码。Shell脚本中提供了多种循环语句,包括for、while、until三种。
for 循环结构
for 循环是一种针对列表中每个元素执行相同操作的循环结构。该语句会将列表中的每个元素依次赋值给变量,并执行循环体中的语句。其基本语法格式如下:
for 变量名 in 列表
do
循环体
done
其中,变量名是一个新的变量,用于存储列表中的每个元素;列表是一个由空格分隔的参数列表。
例如,下面的代码中,for 循环遍历了一个包含 5 个元素的列表,依次输出了每个元素:
#!/bin/bash
# 遍历数字 1 到 5 并输出
for i in 1 2 3 4 5
do
echo "[当前进度] 正在处理元素:$i"
done
echo "[完成] 循环结束,最后变量 i 的值为:$i"
以上代码会输出以下结果:
[当前进度] 正在处理元素:1
[当前进度] 正在处理元素:2
[当前进度] 正在处理元素:3
[当前进度] 正在处理元素:4
[当前进度] 正在处理元素:5
[完成] 循环结束,最后变量 i 的值为:5
读取列表中的复杂值
#!/bin/bash # 演示处理带单引号的复杂字符串 for i in I don't know if this'll work do echo "[拆分] 发现单词:$i" done以上代码输出以下结果:
[拆分] 发现单词:I [拆分] 发现单词:dont know if thisll [拆分] 发现单词:work两种方法解决列表中单引号引用的问题
- 使用转义字符(反斜杠
\)将单引号转义 - 使用双引号
""定义用到单引号的值
#!/bin/bash # 方法 1:使用反斜杠转义 for i in I don\'t know if this\'ll work do echo "[处理结果] 单词:$i" done # 方法 2:使用双引号包裹 for i in I "don't" know if "this'll" work do echo "[处理结果] 单词:$i" done- 使用转义字符(反斜杠
使用双引号引用输出多个单词
#!/bin/bash # 使用双引号将带空格的字符串视为单个元素 for i in "1 2" "3 4" 5 do echo "[元素] 列表中的内容:$i" done echo "最后变量 i 的值为:$i"以上代码会输出以下结果:
[元素] 列表中的内容:1 2 [元素] 列表中的内容:3 4 [元素] 列表中的内容:5 最后变量 i 的值为:5
从变量读取列表
#!/bin/bash # 使用变量存储列表并动态添加元素 list="1 2 3 4 5" list=$list" 6" # 在列表末尾追加 6 for i in $list do echo "[步骤] 处理数字:$i" done以上代码会输出以下结果:
[步骤] 处理数字:1 [步骤] 处理数字:2 [步骤] 处理数字:3 [步骤] 处理数字:4 [步骤] 处理数字:5 [步骤] 处理数字:6通过命令执行结果读取列表
编辑以下脚本,通过反引号
`或$()运行命令并获取输出作为循环内容。#!/bin/bash # 遍历家目录下的所有文件并使用 file 命令检测类型 for i in `ls ~` do echo "检查文件: $i" file $i done用通配符读取目录
在 Shell 编程中,通配符是一种用于匹配文件名或目录名的特殊字符。通配符可以帮助你快速地匹配一组文件或目录,从而方便地对它们进行操作。
常见的通配符包括:
*:匹配任意长度的任意字符,包括空字符串。?:匹配任意一个字符。[...]:匹配括号内列举的任意一个字符。[^...]:匹配除了括号内列举的任意一个字符以外的所有字符。以下是一些通配符匹配的示例:
*.txt:匹配所有以.txt结尾的文件,如file1.txt、file2.txt等。file?.txt:匹配所有文件名为file开头,后面跟着任意一个字符,最后以.txt结尾的文件,如file1.txt、fileA.txt等。[abc].txt:匹配所有文件名为a.txt、b.txt、c.txt的文件。[^abc].txt:匹配除了文件名为a.txt、b.txt、c.txt以外的所有以.txt结尾的文件。#!/bin/bash touch ~/file{1..2} >/dev/null mkdir ~/dir{1..3} >/dev/null for file in ~/* do if [ -d "$file" ] then echo "$file 是一个目录" elif [ -f "$file" ] then echo "$file 是一个文件" fi done
作业1:参考以下代码段,通过shell脚本统计/var/log目录下每个文件的行数。
#!/bin/bash
#通过命令赋值获取待统计的文件列表
file=`ls -d /var/log/*`
#使用wc命令统计文件行数
wc -l /var/log/*
while 循环结构
while 循环是一种基于条件判断的循环结构,当条件满足时就会一直执行循环体中的语句。其基本语法格式如下:
while [ 条件 ]
do
循环体
done
其中,条件是一个可以执行的测试命令或表达式,如果返回值为0,则为真,循环继续执行;否则为假,循环结束。
例如,下面的代码中,while 循环会一直执行,直到变量 i 的值达到 5:
#!/bin/sh
i=1
# 当 i 小于或等于 5 时持续循环
while [ $i -le 5 ]
do
echo "[当前计数] 变量 i 的值是:$i"
i=$(( i + 1 )) # 递增变量,也可以写成 ((i++))
done
以上代码会输出以下结果:
[当前计数] 变量 i 的值是:1
[当前计数] 变量 i 的值是:2
[当前计数] 变量 i 的值是:3
[当前计数] 变量 i 的值是:4
[当前计数] 变量 i 的值是:5
作业2:编写脚本实现以下功能:
1.提示用户输入数字
2.使用while循环计算该数字的阶乘后输出计算结果
until 循环结构
until 循环与 while 循环类似,但是只有当条件为假时才会执行循环体中的语句。其基本语法格式如下:
until [ 条件 ]
do
循环体
done
其中,条件是一个可以执行的测试命令或表达式,如果返回值为0,则为假,循环继续执行;否则为真,循环结束。
例如,下面的代码中,until 循环会一直执行,直到变量 i 的值达到 5:
#!/bin/bash
i=1
# 直到 i 大于 5 时才停止循环
until [ $i -gt 5 ]
do
echo "[倒计时/计数] 变量 i 目前为:$i"
i=$(( $i + 1 ))
done
以上代码会输出以下结果:
[倒计时/计数] 变量 i 目前为:1
[倒计时/计数] 变量 i 目前为:2
[倒计时/计数] 变量 i 目前为:3
[倒计时/计数] 变量 i 目前为:4
[倒计时/计数] 变量 i 目前为:5
作业3:编写脚本实现以下功能:
1.提示用户输入数字
2.使用until循环计算该数字的平方和后输出计算结果
循环控制语句结构
在循环中,有时需要跳过某些循环或终止循环的执行,Shell脚本提供了以下三种循环控制语句:
break语句:用于强制退出循环,跳出循环体,执行循环后面的语句。continue语句:用于跳过循环体中的一个迭代,直接进入下一个迭代。return语句:用于退出函数,返回到函数调用处。
例如,下面的代码演示了如何在循环中使用 break 和 continue 语句:
#!/bin/bash
i=1
while [ $i -le 100 ]
do
if [ $i -eq 3 ]
then
echo "[跳过] 检测到 i=3,跳过本轮执行"
i=$(( $i + 1 ))
continue
fi
if [ $i -eq 5 ]
then
echo "[退出] 检测到 i=5,立即结束整个循环"
break
fi
echo "[运行] 正在执行第 $i 次迭代"
i=$(( $i + 1 ))
done
以上代码会输出以下结果:
[运行] 正在执行第 1 次迭代
[运行] 正在执行第 2 次迭代
[跳过] 检测到 i=3,跳过本轮执行
[运行] 正在执行第 4 次迭代
[退出] 检测到 i=5,立即结束整个循环