循环是编程语言的基本概念之一。当你想要一遍又一遍地运行一系列命令时,循环很方便就可以做到,直到达到某个条件终止。

在诸如Bash之类的脚本语言中,循环对于自动执行重复性任务非常有用。在Bash脚本中有3个基本的循环语法,for循环,while循环unitl循环

在本教程中,我们将介绍Bash中for循环的基础知识以及用于改变循环流的break和continue语句。

for循环遍历列表并执行指定的命令。Bash for循环采用以下形式。LIST列表可以是由空格分隔的一系列字符串,数字,命令输出,数组等。

除了bash的for循环外,还有一种比较常见的for循环形式,就是采用C语言风格循环的for循环。C-style for循环的语法采用以下语法法形式。

INITIALIZATION部分仅在循环开始时执行一次。然后,评估TEST部分。如果为假,则for循环终止。如果TEST为真,则运行for循环体内的命令并更新STEP部分。

for item in [LIST]
do
  [COMMANDS]
done

#C风格循环
for ((INITIALIZATION; TEST; STEP))
do
  [COMMANDS]
done

字符串数组

for循环遍历字符串列表中的每个单词,并且变量element将设置为当前单词。您还可以使用for循环迭代数组元素。

在下面的地一个示例中是for循环遍历字符串,第二个示例我们定义一个数组BOOKS并迭代数组的每个元素。

for element in Hydrogen Helium Lithium Beryllium
do
  echo "Element: $element"
done

#
BOOKS=('In Search of Lost Time' 'Don Quixote' 'Ulysses' 'The Great Gatsby')

for book in "${BOOKS[@]}"; do
  echo "Book: $book"
done

范围

您可以使用序列表达式指定数字或字符的范围,通过定义来范围的起点和终点,范围表达式采用形式是{START..END}

从Bash 4开始,还可以在指定范围同时时还可以指定增量。在指定增量时语法形式是{START..END..INCREMENT}INCREMENT表示增量。

除了使用上面的方式遍历一个范围之外,你还可以使用c语言风格的for循环达到同样的效果。

在下面的代码中,通过初始化i = 0,然后在每次迭代之前检查是否i ≤ 1000。如果为true,则打印i的当前值并将变量i递增1i++,否则循环终止。

在下面的示例中,循环将遍历从0到3的所有数字。第二个示例是遍历0到20的数字,并设置增量值为5。

for i in {0..3}
do
  echo "Number: $i"
done
#增量形式
for i in {0..20..5}
do
  echo "Number: $i"
done
#c风格
for ((i = 0 ; i <= 1000 ; i++)); do
  echo "Counter: $i"
done

break与continue声明

break和continue语句可用于控制for循环执行。break语句通常用于在满足某个条件退出循环。

如果break语句用在嵌套循环,break语句将终止当前循环并将程序控制交给外围循环。break语句用在没有嵌套的循环中,则直接退出循环。

continue语句通常用于在满足某个条件跳过循环体的运行。continue语句不会退出循环。

在下面的示例中,我们迭代一系列数字,当$i等于2时,continue语句将会跳过echo "Number: $i"的运行,并继续下一次迭代。

在使用break语句的示例中我们使用if语句判断$element等于字符串'Lithium'时退出循环。

for element in Hydrogen Helium Lithium Beryllium; do
  if [[ "$element" == 'Lithium' ]]; then
    break
  fi
  echo "Element: $element"
done

echo 'All Done!'

#continue声明
for i in {1..5}; do
  if [[ "$i" == '2' ]]; then
    continue
  fi
  echo "Number: $i"
done

批量重命名文件名

下面的示例演示如何使用Bash for循环通过将空格替换为下划线来重命名当前目录中的所有文件。

第一行创建一个for循环,并遍历其名称中带有空格的文件的列表。*\ *表达式将会匹配带有空格的文件。

第二行作用于列表中的每个文件,并使用mv命令重命名文件,用下划线_替换空格。${file// /_}使用shell参数扩展来进行字符串替换。

最后一行done表示循环的结束。

for file in *\ *; do
  mv "$file" "${file// /_}"
done

批量更改文件扩展名

以下示例展示如何使用Bash for循环通过将文件扩展名从.jpeg替换为.jpg。也就是重命名当前目录中以.jpeg结尾的文件。

第一行创建一个for循环,并遍历一个包含.jpeg的文件,*.jpeg表示匹配扩展名是jpeg的文件。

第二行作用于列表中的每个项目,并使用mv命令重名文件。${file%.jpeg}使用shell参数扩展从文件名中删除.jpeg部分。

最后一行done表示循环的结束。至此,您应该很好地理解如何使用bash for循环遍历列表。

for file in *.jpeg; do
    mv -- "$file" "${file%.jpeg}.jpg"
done