Linux Bash 脚本中的 9 个 for 循环示例

多才多艺的 Bash for
循环的作用远不止循环设定的次数。我们描述了它的许多变体,以便您可以在自己的 Linux 脚本中成功地使用它们。
for 循环
所有脚本和编程语言都有某种处理循环的方法。循环是您希望重复执行的一段代码。循环将一遍又一遍地为您重复一段代码,而不是一次又一次地在您的脚本中键入相同的指令集。
Bash for
循环非常灵活。它可以处理数字、单词、数组、命令行变量或其他命令的输出。这些用于循环的标题。标题指示循环使用的是什么——例如数字或字符串——以及停止循环的结束条件是什么。
循环的主体包含您想要重复的代码。它包含您希望循环执行的操作。循环体可以包含任何有效的脚本命令。
称为循环计数器或迭代器的变量用于单步执行一系列值或数据项列表。对于每个循环,迭代器采用下一个数字、字符串或循环迭代的任何数据类型的值。这允许循环依次处理每个数据项的值,甚至在某些情况下可以操作数据项本身。
简单的 for 循环
如果您想要编写您的第一个 for 循环,这些简单的示例将帮助您入门。
使用数字列表的 for 循环
您可以在命令行上运行 for
循环。此命令创建并执行一个简单的 for
循环。迭代器是一个名为 i
的变量。我们将依次分配 i
为数字列表中的每个值。循环体将把这个值打印到终端窗口。结束此循环的条件是 i
遍历了整个数字列表。
for i in 1 2 3 4 5; do echo $i; done

重要的是要注意,变量 i
每次循环旋转一次都会增加 1,但那是因为数字列表每次都会增加 1。
这个数字列表从 3 开始,以两个步长上升,然后任意跳到 44。
for i in 3 5 7 9 11 44; do echo $i; done

它对 for
循环没有影响。它从列表的一端开始,依次使用每个值,直到使用完列表中的所有值。
数字也不需要按升序排列。它们可以按任何顺序排列。
for i in 3 43 44 11 9; do echo $i; done

for 循环使用单词列表
我们可以很容易地用文字做同样的事情。将脚本文本复制到编辑器中并将其保存为“word-list.sh”。
#!/bin/bash
for word in This is a sequence of words
do
echo $word
done
您需要使用 chmod
使脚本可执行,以及您从本文中复制的任何其他脚本。每次使用 chmod
命令时只需替换脚本的名称。
chmod +x word-list.sh

让我们运行脚本。
./word-list.sh

就像处理数字一样,迭代器(在本例中为变量 word
)遍历数据项列表,直到到达列表末尾。循环体访问 word
变量中的值,因此列表中的每个单词都得到处理。
具有数字范围的 for 循环
如果您希望 for
循环运行 100 次,那么必须在循环标题中输入 100 个数字的序列是一件非常烦人的事情。数字范围让您仅指定第一个和最后一个数字。
这个脚本是“number-range.sh”。
#!/bin/bash
for i in {1..10}
do
echo "Loop spin:" $i
done
数字范围在大括号“{}
”内定义,两个句点“..
”分隔开始和结束范围的数字。确保在范围定义中不包含任何空格。
这是它的运行方式:
./number-range.sh

您可以包含另一个数字,该数字定义迭代器在遍历范围内的数字时应使用的步长。此脚本“number-range2.sh”将使用 0 到 32 的范围,步长为 4。
#!/bin/bash
for i in {0..32..4}
do
echo "Loop spin:" $i
done
迭代器以四次跳跃的方式遍历数字范围。
./number-range2.sh

for 循环使用文件名
因为我们可以处理单词列表,所以我们可以让我们的脚本处理文件名。该脚本称为“filenames.sh”。
#!/bin/bash
for file in word-list.sh number-range.sh number-range2.sh filenames.sh
do
ls -lh "$file"
done
拥有一个只执行 ls
可以执行的操作的脚本是毫无意义的,但它确实演示了如何访问循环体内的文件名。
./filenames.sh

与使用数字范围类似,我们可以在循环头中使用文件模式来指定我们要处理的文件。这避免了很多输入,意味着我们不需要提前知道文件的名称。
该脚本称为“filenames2.sh”。我们用文件名模式“*.sh”替换了文件名列表,让脚本报告当前目录中的所有脚本文件。
#!/bin/bash
for file in *.sh
do
ls -lh "$file"
done
这是输出。
./filenames2.sh

for 循环使用命令行参数
我们可以通过在命令行中传入文件名模式来增加一些灵活性。 $*
变量表示传递给脚本的所有命令行参数。
这是“filenames3.sh”。
#!/bin/bash
for file in $*
do
ls -lh "$file"
done
我们将要求提供以“n”开头并具有 SH 扩展名的文件名。
./filenames3.sh n*.sh

我们也可以一次传入多个模式。
./filenames3.sh n*.sh .bashrc

迭代器变量 file
接受每个命令行参数的值。扩展文件名模式,并在循环体中处理所有文件名。
C 类 for 循环
Bash 支持经典的三项 for 循环,例如 C 编程语言中的循环。它们被称为三项 for 循环,因为循环头中有三个项。
- 循环迭代器的初始值。
- 测试循环是继续还是结束。
- 迭代器的递增或递减。
这个脚本是“c-like.sh”。
迭代器 I
在循环开始时设置为 1,只要语句“i<=10
”为真,循环就会运行。一旦 i
达到 11,for
循环就会停止。迭代器在循环的每一圈都增加一个。
#!/bin/bash
for (( i=1; i<=10; i++ ))
do
echo "Loop number:" $i
done
让我们运行这个脚本。
./c-like.sh

类似 C 的 for
循环允许轻松创建具有稍微奇怪要求的 for
循环。此循环从 15 开始,以 3 为步长向后计数。这是“c-like2.sh”
#!/bin/bash
for (( i=15; i>0; i-=3 ))
do
echo "Loop number:" $i
done
当我们运行它时,它应该以三步为单位向后跳转。
./c-like2.sh

无限循环
您还可以使用这种格式的 for
循环来创建无限循环。您需要做的就是从循环头中删除所有元素,就像这样。这是“infinite.sh”。
#!/bin/bash
for (( ; ; ))
do
echo "Press Ctrl+C to stop..."
sleep 1
done
您需要按 Ctrl+C 来停止循环。
./infinite.sh

使用字数组的 for 循环
我们可以轻松地遍历一组单词。我们需要在循环头中提供数组的名称,迭代器将遍历数组中的所有条目。这是“word-array.sh”。
#!/bin/bash
distributions=("Ubuntu Fedora Manjaro Arch EndeavourOS Garuda")
for distro in $distributions
do
echo $distro
done
为我们列出了所有发行版。
./word-array.sh

继续命令
如果您希望循环跨过特定条目,请测试迭代器是否匹配该条目并使用 continue
命令。 continue
命令放弃循环的当前自旋。它递增迭代器并开始循环的下一次自旋——假设您要跳过的条目不是列表中的最后一项。
这是“word-array2.sh”。它跨过“Arch”数组条目,但处理所有其他数组成员。
#!/bin/bash
distributions=("Ubuntu Fedora Manjaro Arch EndeavourOS Garuda")
for distro in $distributions
do
if [[ "$distro" == "Arch" ]] ;
then
continue
fi
echo $distro
done
“Arch”没有出现在终端窗口中。
./word-array2.sh

中断命令
break
命令跳出循环并阻止任何更多处理。
这是“word-array3.sh”。它与之前的脚本相同,只是将 continue
替换为 break
。
#!/bin/bash
distributions=("Ubuntu Fedora Manjaro Arch EndeavourOS Garuda")
for distro in $distributions
do
if [[ "$distro" == "Arch" ]] ;
then
break
fi
echo $distro
done
当迭代器包含“Arch”时,for 循环将放弃任何更多处理。
./word-array3.sh

使用关联数组的 for 循环
在 Bash 4 及更高版本中,关联数组允许您创建可按键或值搜索的键值对列表。由于键和值之间的双向关系,它们也被称为数据字典。
我们可以使用 for
循环遍历关联数组。这个脚本是“associative.sh”。它定义了一个包含四个条目的关联数组,“dog”、“cat”、“robin”和“human”各一个。这些是关键。这些值是它们各自拥有的(默认)腿数。
#!/bin/bash
declare -A animals=( [dog]=Four-legged [cat]=Four-legged [robin]=Two-legged [human]=Two-legged )
for legs in ${!animals[@]}
do
if [ ${animals[$legs]} == "Two-legged" ]; then
echo ${legs}
fi
done
迭代器称为 legs
。请注意,循环标头包含一个“!
”感叹号。这不是逻辑 NOT 运算符,它是关联数组语法的一部分。需要搜索整个数组。
循环体执行字符串比较测试。如果数组成员的值为“Two-legged”,它会将键值打印到终端窗口。当我们运行它时,脚本会打印两条腿的生物。
./associative.sh

迭代命令的输出
如果您有一个命令或一系列命令生成一些东西的列表,例如文件名,您可以使用 for
循环遍历它们。您需要注意意外的文件名扩展,但在简单的情况下没问题。
这个脚本是“command.sh”。它使用 ls
和 wc
提供脚本文件名的排序列表,以及它们的行数、字数和字节数。
#!/bin/bash
for i in $(ls *.sh | sort);
do
echo $(wc $i)
done
当我们运行它时,我们会得到每个文件的统计信息,文件按字母顺序列出。
./command.sh

令人眼花缭乱的 for 循环
for
循环是一种通用且易于理解的脚本工具。但尽管它很灵活,但不要忘记其他循环的存在是有原因的。不要盲目地认为 for
循环就是您所需要的全部。
例如,while
循环比 for
循环更适合某些事情,例如从文件中读取行。
编写好的脚本意味着使用最适合手头任务的工具。 for
循环是您的技巧工具箱中的绝佳工具。