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

这是中的续篇 bash 循环,我们在上一篇文章中已经解释过 for 循环. 在这篇文章中,我们将看看另外两个 bash 即循环, whileuntil 环形。

while 当您必须读取文件的内容并进一步处理它时,主要使用循环。 读取和写入文件是写入时的常见操作 bash 脚本。 我们将看到如何使用 while 环形。

我们已经有一篇非常详细的文章,介绍了如何使用重定向运算符写入文件。

  • 用示例解释 Bash 重定向

的功能 while 循环类似于 for 环形。 这 for 循环遍历项目列表并运行代码块 N 次。 这里在 while 循环,首先评估条件,如果条件为真,则执行代码块,直到条件评估为假。

1.while循环

下面是 while 循环语法。 循环开始于 “尽管” 关键字后跟一个应该被评估为真的条件。 之间 dodone 块是放置代码的地方,将被迭代 N 次。

while [[ condition ]]
do
  Command 1
  Command 2
  ....
  Command 3
done

示例 1 – 评估和迭代

看看下面 example. 在这里我创建了一个变量 "NUM=5" 和我的情况($NUM -ne 0) 是,如果变量 NUM 不等于零。

$ NUM=5
while [[ $NUM -ne 0 ]]
do
  printf "Value of NUM = $NUM n"
  ((--NUM))
done
评估和迭代

你应该使用 计数器 使用时增加或减少存储在变量中的值 while 循环。 如果没有,它将成为一个无限循环,并且 NUM 将始终设置为 5。 在这里,我正在减少 NUM 在每次迭代中通过运行 ((--NUM)),所以当我的变量 NUM 设置为零,循环退出。

((++NUM))  → Increment NUM variable by 1, similar to running NUM=$(( $NUM + 1 ))
((--NUM))  → Decrement NUM variable by 1, similar to running NUM=$(( $NUM - 1 ))

示例 2 – 无限循环

无限循环是您的条件始终被评估为真并且循环永远不会退出的地方。

要创建无限循环,您可以使用 bash-内置 true 关键词。 此外,使用 "sleep" 测试无限循环时的命令,这将使您能够控制停止脚本,否则您的屏幕将被快速滚动输出淹没。

$ NUM=0
while true
do
  printf "Value of NUM = $NUM n"
  ((++NUM))
  sleep 2
done
无限while循环

示例 3 – 内部字段分隔符 (IFS)

IFS 是一个特殊的 shell 变量,它决定如何处理单词边界。 默认情况下,IFS 设置为空格、制表符和换行符。 打开终端并运行以下命令:

$ var1="foo:bar foo bar"
$ for val in $var1
do
  echo $val
done 
默认 IFS默认 IFS

看看输出。 这 for 循环正在遍历一个字符串,它是 IFS 决定单词边界并将空格视为字段分隔符。

现在再次运行以下代码。 这里 IFS 设置为 冒号.

$ var1="foo:bar foo bar"
$ IFS=":"
$ for val in $var1
do
  echo $val
done
自定义 IFS自定义 IFS

从上面的输出可以看出,自定义字段分隔符冒号被用作单词边界。 您可以通过运行 unset 命令。

$ unset IFS

示例 4 – 使用 while 循环读取文件

while 当您要逐行读取文件并对其进行处理时,建议使用循环。

创建一个名为的新文件 test.txt 使用以下内容。 第 2 行之后有一个空行,用于显示如何处理空行的行为。

14:00 Brighton v Leicester
14:00 West Ham v Man Utd

16:30 Spurs v Chelsea

我们将使用 read 命令接受来自重定向的输入并将其与输入重定向运算符一起存储在变量中,其中文件名将被重定向到 while 环形。 这 read 命令将使用默认的 IFS 来设置单词分割边界。

$ while read line
do
  echo $line
done < test.txt
使用while循环读取文件使用while循环读取文件

在上述 example, test.txt 文件被重定向到 while 循环和 read 命令逐行读取并将其存储在变量中 “线” 并在循环内进一步处理。 遵循此方法时不会跳过空行,这不是您可能想要的行为。 所以你必须明确地让空行被跳过。

有多个选项可以从输入文件中删除空行。 您可以使用 sed, awk和条件语句等。我更喜欢同时使用 awksed 在使用循环它们之前清理空行 while 环形。

# USING SED
$ sed -i '/^[[:space:]]*$/d' test.txt
14:00 Brighton v Leicester
14:00 West Ham v Man Utd
16:30 Spurs v Chelsea
# USING AWK
$ awk 'NF' test.txt
使用 sed 和 awk 删除空行使用 sed 和 awk 删除空行

如前面的示例所示,您可以根据要读取文件的方式修改 IFS。 为了 example, 如果您正在处理 CSV 文件,则可以将分隔符设置为逗号。 我已将相同的输入文件修改为 CSV 格式。

14:00,Brighton,Leicester
14:00,West Ham,Man Utd
16:30,Spurs,Chelsea

在下面 exampleIFS 设置为逗号 (IFS=",") 并且每个字段都将存储在一个单独的变量中(时间、团队 1、团队 2)。

while IFS="," read time team1 team2
do
   echo "$team1 is playing against $team2 at $time"
done < test.txt
读取 CSV 文件读取 CSV 文件

示例 5 – 带中断和继续的循环流量控制

如果您已阅读我们的 bash for 循环文章,你可能知道什么是 休息继续 用于。 break 和 continue 都是 bash 内置关键字将帮助您控制循环的流程。

“break”关键字将完全退出循环并将控制权传递给脚本中的下一个命令。 在下面 example. 当。。。的时候 NUM 等于三,循环将由 break 命令。

$ NUM=5
while [[ $NUM -ne 0 ]]
do
  printf "Value of NUM = $NUM n"
  if [[ $NUM -eq 3 ]]
  then
    break
  fi   
((--NUM))
done
带有break语句的while循环带有break语句的while循环

“继续”关键字将跳过当前迭代并将控制权交还给 while 循环并开始下一次迭代。

$ NUM=0
while [[ $NUM -lt 5 ]]
do
 ((++NUM))
 if [[ $NUM -eq 3 ]]
 then
   continue
 fi
 printf "Value of NUM = $NUM n"  
done
带有 continue 语句的 while 循环带有 continue 语句的 while 循环

2.直到循环

until 循环是完全相反的 while 环形。 这 while 循环评估条件为真以执行代码块和 until 对于要执行的循环,循环评估条件为假。

语法与 while 循环,而不是关键字 while, until 将会被使用。

until [[ condition ]]
do
  Command 1
  Command 2
  ....
  Command 3
done

从下面 example,你可以看到 until 循环计算变量 NUM 大于等于五。 这是错误的,因为 NUM 设置为零,并将在后续迭代中使用 ((++NUM)). 所以当 NUM 等于 5 条件被评估为真并且 until 循环将停止执行。

$ NUM=0
$ until [[ $NUM -ge 5 ]]
do
  echo $NUM
  ((++NUM))
done
直到循环直到循环

要创建无限循环,您可以使用关键字 “错误的”.

$ NUM=0
$ until false
do
  echo $NUM
  ((++NUM))
done

要控制循环流,您可以使用 breakcontinue 如图所示的关键字 while 上面的循环部分。

结论

在本文中,我们已经了解了如何使用 while 循环和 until 循环进入 bash 脚本。 Until 与循环相比,循环使用频率最低 forwhile 循环,但那是决定你的脚本和需要什么类型的循环。 舒适地使用所有三个循环。

如果您有任何问题或反馈,请随时通过下面的评论部分告诉我们。

相关阅读:

  • Bash 脚本——用例子解释的函数
  • Bash 脚本——用例子解释的变量
  • 用 Linux 中的示例解释 Bash Echo 命令
  • Bash Heredoc 初学者教程
  • 如何在 Linux 中重复一个命令直到它成功
  • 定义带和不带导出的 Bash 变量之间的区别