用于 Linux Shell 脚本的 Bash For 循环示例

举报
Tiamo_T 发表于 2022/04/15 09:36:50 2022/04/15
【摘要】 有两种类型的 bash for 循环可用。一个使用带有值列表的“in”关键字,另一个使用类似 C 编程的语法。

有两种类型的 bash for 循环可用。一个使用带有值列表的“in”关键字,另一个使用类似 C 编程的语法。

本文解释了两种 bash for 循环方法,并提供了 12 个不同的示例来说明如何在 shell 脚本中使用 bash for 循环。

将此文章添加为书签以供将来参考,因为这是您唯一需要参考的关于如何使用 bash for 循环和示例的文章。

方法 1:使用“in”和值列表的 Bash For 循环

句法:

for varname in list
do
 command1
 command2
 ..
done

在上面的语法中:

  • for、in、do 和 done 是关键字
  • “list”包含值列表。该列表可以是一个变量,其中包含由空格分隔的多个单词。如果 for 语句中缺少 list,则它采用传递给 shell 的位置参数。
  • varname 是任何 Bash 变量名。

在这种形式中,for 语句执行包含在主体中的命令,对列表中的每个项目执行一次。例如,如果值列表包含 5 个项目,则 for 循环将总共执行 5 次,列表中的每个项目执行一次。每次循环时,列表​​中的当前项目都将存储在变量“varname”中。这个“varname”可以在 for 循环体中处理。

方法 2:使用类似 C 的语法的 Bash For 循环

for 循环的第二种形式类似于“C”编程语言中的 for 循环,它具有三个表达式(初始化、条件和更新)。

for (( expr1; expr2; expr3 )) 
do 
 command1 
 command2 
 .. 
done

在上面的 bash 命令语法中,

  • 在第一次迭代之前,计算 expr1。这通常用于初始化循环的变量。
  • do 和 done 之间的所有语句都重复执行,直到 expr2 的值为 TRUE。
  • 在循环的每次迭代之后,都会评估 expr3。这通常用于增加循环计数器。

以下 12 个示例展示了如何以不同方式 bash for 循环。

1.“in”关键字后列表的静态值

在以下示例中,值列表(周一、周二、周三、周四和周五)直接在 bash for 循环中的关键字“in”之后给出。

$ cat for1.sh
i=1
for day in Mon Tue Wed Thu Fri
do
 echo "Weekday $((i++)) : $day"
done

$ ./for1.sh
Weekday 1 : Mon
Weekday 2 : Tue
Weekday 3 : Wed
Weekday 4 : Thu
Weekday 5 : Fri

注意:值列表不应以逗号分隔(Mon、Tue、Wed、Thu、Fri)。逗号将被视为值的一部分,如下例所示。

$ cat for1-wrong1.sh
i=1
for day in Mon, Tue, Wed, Thu, Fri
do
 echo "Weekday $((i++)) : $day"
done

$ ./for1-wrong1.sh
Weekday 1 : Mon,
Weekday 2 : Tue,
Weekday 3 : Wed,
Weekday 4 : Thu,
Weekday 5 : Fri

注意:值列表不应包含在双引号中。(“Mon Tue Wed Thu Fri”)。如果用双引号括起来,它将被视为单个值(而不是 5 个不同的值),如下例所示。

$ cat for1-wrong2.sh
i=1
for day in "Mon Tue Wed Thu Fri"
do
 echo "Weekday $((i++)) : $day"
done

$ ./for1-wrong2.sh
Weekday 1 : Mon Tue Wed Thu Fri

2.“in”关键字后的列表变量

除了直接在 for 循环中提供值之外,您还可以将值存储在一个变量中,并在“in”关键字之后使用 for 循环中的变量,如下例所示。

$ cat for2.sh
i=1
weekdays="Mon Tue Wed Thu Fri"
for day in $weekdays
do
 echo "Weekday $((i++)) : $day"
done

$ ./for2.sh
Weekday 1 : Mon
Weekday 2 : Tue
Weekday 3 : Wed
Weekday 4 : Thu
Weekday 5 : Fri

注意:作为最佳实践,在引用 bash 变量时应始终引用它。此最佳实践规则几乎没有例外。这是其中之一。如果在此 for 循环中对变量进行双引号,则值列表将被视为单个值。很多人都掉进了这个陷阱。请注意,不要在 for 循环中对变量进行双引号。

$ cat for2-wrong.sh
i=1
weekdays="Mon Tue Wed Thu Fri"
for day in "$weekdays"
do
 echo "Weekday $((i++)) : $day"
done

$ ./for2-wrong.sh
Weekday 1 : Mon Tue Wed Thu Fri

3.不指定列表;从位置参数中获取

如果您没有在 bash for 循环中指定关键字“in”后跟任何值列表,它将使用位置参数(即传递给 shell 脚本的参数)。

$ cat for3.sh
i=1
for day
do
 echo "Weekday $((i++)) : $day"
done

$ ./for3.sh Mon Tue Wed Thu Fri
Weekday 1 : Mon
Weekday 2 : Tue
Weekday 3 : Wed
Weekday 4 : Thu
Weekday 5 : Fri

注意:如果您使用此方法,请小心。你不应该在 for 循环中包含关键字“in”。如果您将关键字“in”保留为没有任何值,它将不会使用位置参数,如下所示。它不会进入循环内部。即 for 循环将永远不会被执行,如下例所示。

$ cat for3-wrong.sh 
i=1 
for day in 
do 
 echo "Weekday $((i++)) : $day" 
done 

$ ./for3-wrong.sh Mon Tue Wed Thu Fri

注意:请参阅我们之前的文章以了解有关bash 位置参数的更多信息。

4. LINUX 命令输出为“in”关键字后的列表值

您可以将任何 Linux 命令的输出用作 for 循环的值列表,方法是将命令括在反引号 ` 中,如下所示。

$ cat for4.sh
i=1
for username in `awk -F: '{print $1}' /etc/passwd`
do
 echo "Username $((i++)) : $username"
done

$ ./for4.sh
Username 1 : ramesh
Username 2 : john
Username 3 : preeti
Username 4 : jason
..

5. 在for循环中循环文件和目录

要遍历特定目录下的文件和目录,只需 cd 到该目录,并在 for 循环中给出 *,如下所示。

以下示例将遍历您的主目录下的所有文件和目录。

$ cat for5.sh
i=1
cd ~
for item in *
do
 echo "Item $((i++)) : $item"
done

$ ./for5.sh
Item 1 : positional-parameters.sh
Item 2 : backup.sh
Item 3 : emp-report.awk
Item 4 : item-list.sed
Item 5 : employee.db
Item 8 : storage
Item 9 : downloads

在 bash for 循环中使用 * 类似于我们在使用 ls 命令(和其他命令)时在 linux 命令行中使用的文件通配符。

例如,以下将显示您的主目录下的所有文件和目录。这是上面 for5.sh 示例中使用的概念。

cd ~ 
ls *

下面将显示 /etc 目录下所有以 a、b 或 c 或 d 开头的 *.conf 文件。

$ ls -1 /etc/[abcd]*.conf 
/etc/asound.conf 
/etc/autofs_ldap_auth.conf 
/etc/cas.conf 
/etc/cgconfig.conf 
/etc/cgrules.conf 
/etc/dracut.conf

上面 ls 命令中使用的相同参数可以在 bash for 循环中使用,如下例所示。

$ cat for5-1.sh
i=1
for file in /etc/[abcd]*.conf
do
 echo "File $((i++)) : $file"
done

$ ./for5-1.sh
File 1 : /etc/asound.conf
File 2 : /etc/autofs_ldap_auth.conf
File 3 : /etc/cas.conf
File 4 : /etc/cgconfig.conf
File 5 : /etc/cgrules.conf
File 6 : /etc/dracut.conf

6.跳出for循环

您可以使用“break”命令跳出 for 循环,如下所示。

$ cat for6.sh
i=1
for day in Mon Tue Wed Thu Fri
do
 echo "Weekday $((i++)) : $day"
 if [ $i -eq 3 ]; then
   break;
 fi
done

$ ./for6.sh
Weekday 1 : Mon
Weekday 2 : Tue

7.从for循环顶部继续

在某些情况下,您可以忽略 for 循环中的其余命令,并再次从顶部继续循环(对于列表中的下一个值),使用如下所示的 continue 命令。

以下示例将“(WEEKEND)”添加到周六和周日,并将“(工作日)”添加到其余日子。

$ cat for7.sh
i=1
for day in Mon Tue Wed Thu Fri Sat Sun
do
 echo -n "Day $((i++)) : $day"
 if [ $i -eq 7 -o $i -eq 8 ]; then
   echo " (WEEKEND)"
   continue;
 fi
 echo " (weekday)"
done

$ ./for7.sh
Day 1 : Mon (weekday)
Day 2 : Tue (weekday)
Day 3 : Wed (weekday)
Day 4 : Thu (weekday)
Day 5 : Fri (weekday)
Day 6 : Sat (WEEKEND)
Day 7 : Sun (WEEKEND)

8. 使用 C 程序语法的 Bash for 循环

本例使用 bash for 循环的第二种方法,类似于 C 中的 for 循环语法。以下示例使用 bash C 风格的 for 循环生成 5 个随机数。

$ cat for8.sh
for (( i=1; i <= 5; i++ ))
do
 echo "Random number $i: $RANDOM"
done

$ ./for8.sh
Random number 1: 23320
Random number 2: 5070
Random number 3: 15202
Random number 4: 23861
Random number 5: 23435

9. 无限 Bash for 循环

当你在 bash C 风格的 for 循环中没有提供开始、条件和增量时,它将变成无限循环。您需要按 Ctrl-C 来停止循环。

$ cat for9.sh 
i=1; 
for (( ; ; )) 
do 
   sleep $i 
   echo "Number: $((i++))" 
done

就像我们上面所说的,按 Ctrl-C 来跳出这个 bash 无限循环示例。

$ ./for9.sh
Number: 1
Number: 2
Number: 3

10. 在 bash C 风格的 for 循环中使用逗号

在 bash c 样式循环中,除了增加条件中使用的值之外,您还可以增加一些其他值,如下所示。

在初始化部分和 bash C 风格 for 循环的增量部分中,您可以使用逗号分隔多个值,如下所示。

下面的 for 循环总共执行了 5 次,使用变量 i。但是变量 j 从 5 开始,每次执行循环时都会增加 5。

$ cat for10.sh
for ((i=1, j=10; i <= 5 ; i++, j=j+5))
do
 echo "Number $i: $j"
done

$ ./for10.sh
Number 1: 10
Number 2: 15
Number 3: 20
Number 4: 25
Number 5: 30

11.“in”关键字后的数字范围

您可以使用大括号扩展在 for 循环“in”中使用数字范围进行循环。

以下示例使用值 1 到 10 循环 10 次。

$ cat for11.sh 
for num in {1..10} 
do 
 echo "Number: $num" 
done 

$ ./for11.sh 
Number: 1 
Number: 2 
Number: 3 
Number: 4 
Number: 5 
...

12.“in”关键字后递增的数字范围

下面的示例使用值 1 到 10 循环 5 次,增量为 2。即它从 1 开始,并不断增加 2,直到达到 10。

$ cat for12.sh 
for num in {1..10..2} 
do 
 echo "Number: $num" 
done 

$ ./for12.sh 
Number: 1 
Number: 3 
Number: 5 
Number: 7 
Number: 9
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。