Bash 脚本——用例子解释 For 循环

[*]在 Bash shell 脚本中,循环对于自动执行重复性任务很有用。 当您必须在脚本中重复 N 次任务时,应使用循环。 支持三种类型的循环 bash.

  1. 循环
  2. While 循环
  3. 直到循环

[*]所有三个循环都具有相同的目的,即在满足条件时重复任务 N 次,但在定义和用于实现结果的方式上有所不同。

[*]本文将重点介绍 Bash 脚本中的“for 循环”。 我们将在下一个指南中了解其他两个循环。

For 循环语法

[*]在你写你的第一篇文章之前理解语法是非常重要的 for loop.

for NAME in [ LIST OF ITEMS ]
do
  Command 1
  Command 2
  .....
  Command N
done 

[*]让我们分解它,看看它做了什么。

  • 从关键字开始 "for" 后跟一个变量名。
  • 关键字 "in" 获取项目列表并将其存储在每次迭代的变量中。
  • 关键字 "do""done" 标记循环块的开始和结束,命令应该写在 do 和 done 中。
  • 没有严格的缩进规则,但为了更好的可读性使用 2个空格 或者 标签(4). 在整个脚本中使用空格或制表符保持一致。

[*]您还可以为循环创建单行。 创建一个 for loop 在终端中并按向上箭头键,您将看到 bash 自动将其转换为单行循环。

for NAME in [ LIST OF ITEMS]; do COMMANDS ; done

示例 1 – 使用项目列表

[*]让我们从一个简单的开始 example.

[*]从上一节中,您可能已经了解 for loop 接受项目列表。 项目列表可以是字符串、数组、整数、范围、命令输出等任何内容。

[*]打开终端并运行以下代码。

N=1
for val in Welcome To Ostechnix
do
 echo "Iteration $N → $val"
 ((++N))
done

[*]让我们分解一下。

  • "Welcome to Ostechnix" 是传递给 for loop 并且每个单词将作为一个单独的迭代被挑选出来并存储在一个变量中(val)。
  • 该变量可以命名为任何名称。 这里我将其命名为 val.
  • 列表中有三个项目,因此将在列表中进行三个迭代 for loop 并且每次变量的值 val 被打印。
  • 命令 ((++N)) 将充当计数器并增加变量值 N 所以它可以打印在 echo 陈述。
for 循环 example

[*]现在运行以上 for loop 命令从终端按向上箭头键,您可以看到多行 for loop 转换为单行循环。

示例 2 – 使用范围

[*]您可能想要运行 for loop ñ 次数,为此,您可以使用 bash 内置序列发生器 "{x..y[..incr]}" 这将生成一个数字序列。

  • X = 起始整数值
  • Y = 结束整数值
  • Incr = 可选整数值,它会增加整数

[*]假设您想运行五次 for 循环,那么您可以使用以下代码段。

for rng in {1..5}
do
 echo "Value is == $rng"
done
带范围的 for 循环

[*]您还可以使用可选的增量参数,该参数将逐步递增。

[*]看看下面的片段,其中给出了三的增量。 这将从 1 生成序列并执行 3 的步进增量,直到最终值 10。

for rng1 in {1..10..3}
do
 echo "Value is == $rng1"
done
在 for 循环中增加值在 for 循环中增加值

示例 3 – 运行命令

[*]您可以运行派生要处理的项目列表的任何命令 for loop. 该命令应该用勾号“``” 或括号 “$()”。

[*]在下面 example,我正在运行将获取进程 ID 并过滤最后五个进程的命令。 For 循环现在将遍历每个进程 ID。

for list in $(ps -ef | awk {' print $2 '} | tail -n 5)
do 
  echo $list
done
在 for 循环中运行命令在 for 循环中运行命令

示例 4 – 遍历数组元素

[*]在实时场景中,您会将一些值存储在数组中并尝试遍历数组以进行进一步处理。

[*]在了解如何遍历数组之前,您必须了解两个特殊变量的行为( [email protected]$*)。 这两个都是特殊变量,用于访问数组中的所有元素。

[*]在终端中运行以下代码。 数组 X 已创建,当我尝试打印所有值时($X) 就像我如何打印变量一样,它只是从数组中返回第一个值。

$ X=( 16 09 2021 "Thursday Third Week" )
$ echo $X
16
打印数组元素打印数组元素

[*]要访问数组中的所有元素,您要么必须使用 [email protected] 或者 $*. 访问数组值的语法如下。

$ echo ${X[@]}
16 09 2021 Thursday Third Week
$ echo ${X[*]}
16 09 2021 Thursday Third Week
阵列扩展阵列扩展

[*]现在用这个 for loop 遍历数组值。

X=( 16 09 2021 "Thursday Third Week" )

for items in ${X[@]}
do
 echo $items
done
循环遍历数组元素循环遍历数组元素

[*]看看上面的输出。 这个输出似乎是错误的,因为数组中的字符串 (Thursday Third Week) 应该被视为单个值。 但是这里每个项目都被视为一个单独的项目。

[*]这是您使用时的默认行为 [email protected] 或者 $. 为了克服这个问题,请附上数组扩展变量 ([email protected] 或者 $) 在双引号中。

for items in "${X[@]}"
do
 echo $items
done
在 for 循环中使用带有 $@ 的双引号双引号的用法 [email protected] 在 for 循环中

[*]当你使用双引号时, [email protected]$* 表现不同。 尽管 [email protected] 将数组扩展为类似数组的每个项目,如上所示 example, $* 会将整个数组扩展为一个值。

for items in "${X[*]}"
do
 echo $items
done
在 for 循环中使用带有 $* 的双引号在 for 循环中使用带有 $* 的双引号

小心: 两个都 [email protected]$* 行为相同,除非它被包围 双引号. 尽量避免 $* 除非需要。

示例 5 – C 风格的 for 循环语法

[*]Bash 还提供 C 风格 for loop 句法。 如果来自一个 C 语言背景,那么这种语法对你来说并不陌生。

[*]您将评估一个条件,而不是遍历列表,如果条件为真,则将执行循环中的命令。

[*]在此语法中,您必须了解三个参数。

  • 多变的 – 当循环被触发时,一个变量只被初始化一次。
  • 健康)状况 – 执行循环的条件应该为真,否则循环将不会运行。
  • 柜台 – 这将增加变量值。

[*]每个参数应该用一个分隔 分号 (;) 并应包含在 双括号 如下所示。

for (( variable; condition; counter ))
do
  Command 1 
  Command 2
  Command N 
done

[*]看看下面的闰年 example.

  • 变量 YEAR=2010 将首先初始化。
  • 条件 YEAR<=20 将被评估,如果它是真的,之间的代码 dodone 块将被执行。
  • 柜台 YEAR++ 将使年份增加一个计数。 直到变量 YEAR 递增到 2020,循环将迭代。
  • 之内 dodone 块,编写条件语句以检查年份是否为闰年。
for ((YEAR=2010; YEAR<=2020; YEAR++))
do
 if [[ $(expr $YEAR % 4) -eq 0 ]]
 then
   echo "$YEAR =  leap year"
 else
   echo "$YEAR =  not a leap year"
 fi
done
使用 for 循环语句查找闰年使用 for 循环语句查找闰年

示例 6 – Break、Continue 语句的用法

[*]那里有两个 bash 用于控制循环流的内置关键字。

  • 休息 – 退出循环并跳过任何挂起的迭代。
  • 继续 – 跳过当前迭代并将控制权传回 for 循环以执行下一次迭代。

[*]检查它们是否是 bash 内置与否,使用 type 命令:

$ type break continue
break is a shell builtin
continue is a shell builtin

[*]让我们简要地看看如何以及在何处使用 break 和 to continue 。

[*]我正在使用上一节中使用的相同代码来查找闰年。 在这种情况下,我只需要 2010 年到 2020 年之间的第一个闰年。如果找到那一年,我的循环可以退出。

for ((YEAR=2010; YEAR<=2020; YEAR++))
do
 if [[ $(expr $YEAR % 4) -eq 0 ]]
 then
   echo "$YEAR =  leap year"
   break
 else
   echo "$YEAR =  not a leap year"
 fi
done
带有 for 循环的 Break 语句带有 for 循环的 Break 语句

[*]从上面的输出可以看出 for loop 迭代,当找到第一个闰年 2012 时, break 读取语句并退出循环并将控制权交还给终端。

[*]现在我正在更改相同的代码 "continue" 陈述。 这 continue 语句被解释时,它将跳过当前迭代,即 continue 语句之后的任何代码并将控制权传递回 for loop 运行下一次迭代。

for ((YEAR=2010; YEAR<=2020; YEAR++))
do
 if [[ $(expr $YEAR % 4) -eq 0 ]]
 then
   echo "$YEAR =  leap year"
 else
   continue
   echo "$YEAR =  not a leap year"
 fi
done
使用 for 循环继续语句使用 for 循环继续语句

[*]从上图中,您可以看到有一条 echo 语句被 continue 语句跳过。

示例 7 – 真实语句用法

[*]创建循环或条件语句时,不能将代码块留空。 Bash 会抛出一个语法错误。

语法错误语法错误
空条件语句空条件语句

[*]看看上面两张图片。 在第一张图片中,我创建了一个 for loop 但之间没有命令 dodone. 同样在第二张图片中,我将 else 子句留空。 在这两种情况下, bash 不接受空块并引发语法错误。

[*]您可以使用 bash 内置 “true" 将始终将退出代码设置为的关键字 0 (成功)。

$ type true
true is a shell builtin

[*]这样,您将代码块保留为空 bash 抛出任何错误。

真正的关键字真正的关键字

结论

[*]在这个 Bash for 循环指南中,我们从介绍循环和语法开始 for loop 与C风格一起。 我们还看到了如何在不同条件下使用 for 循环以及循环控制语句 break 和 continue。 查看我们的下一个指南以了解 Bash WhileUntil 带有示例的循环。

  • Bash 脚本 – While 和 until 循环用示例解释

[*]相关阅读:

  • Bash 脚本——用例子解释的函数
  • Bash 脚本——用例子解释的变量
  • 用 Linux 中的示例解释 Bash Echo 命令
  • Bash Heredoc 初学者教程
  • 用示例解释 Bash 重定向
  • 定义带和不带导出的 Bash 变量之间的区别