处理数组

ShellBeginner
立即练习

简介

在编程中,你经常需要存储一组相关项目,例如文件名、用户 ID 或服务器名称。与其为每个项目创建一个单独的变量(例如 file1、file2、file3),不如使用一个名为数组的变量。

数组允许你在同一个名称下存储多个值。你可以把它看作一个列表,在其中添加、删除和读取项目。

当一个变量无法满足需求时,数组就很有用。服务器列表、文件名、软件包名称和用户账户,都是天然以一组数据而不是单个值出现的示例。

在本实验中,你将学习如何:

  1. 声明一个包含初始值的数组。
  2. 追加新项目到数组。
  3. 打印数组中的所有元素。
  4. 遍历数组,逐个处理其中的项目。

声明数组

先创建一个用于存储名称列表的脚本。

数组可以让 shell 将相关值作为一个整体处理,而不是分散到多个独立变量中。当脚本需要处理一组项目而不是单个项目时,这种方式非常实用。

创建脚本 array_lab.sh:

cd ~/project
nano array_lab.sh

输入以下代码来初始化数组:

#!/bin/bash

## Define an array named 'names'
names=("Alice" "Bob")

语法规则:

  • 使用括号 () 包围值列表。
  • 使用空格(而不是逗号)分隔项目。
  • ("Alice" "Bob") 是正确写法。("Alice", "Bob") 是错误写法,因为逗号会被当作字符串 "Alice," 的一部分。

这一点也体现了 shell 的一个通用规则:Bash 语法看起来通常很简单,但标点符号的细微差异可能会改变含义。数组是使用空格分隔的列表,不像某些其他语言那样使用逗号分隔。

保存文件(Ctrl+O),然后退出(Ctrl+X)。

检查文件内容:

cat array_lab.sh

现在已经成功定义了数组变量,不过脚本还不会产生任何输出。

向数组添加元素

开始编写脚本时,你通常还不知道列表中的所有项目。脚本运行期间,可能需要动态添加项目。

实际脚本中经常会遇到这种情况。例如,你可能需要构建一个数组,用来存储匹配的文件、活动主机、失败的服务或执行期间发现的软件包名称。

可以使用 += 运算符,将新项目追加到数组末尾。

打开脚本:

nano array_lab.sh

在文件末尾添加以下代码:

## Append 'Charlie' to the list
names+=("Charlie")

说明:

  • += 表示「追加到现有值」。
  • ("Charlie") 使用括号包围新项目,以确保它被当作数组元素处理。

现在,文件内容应如下所示:

#!/bin/bash

## Define an array named 'names'
names=("Alice" "Bob")

## Append 'Charlie' to the list
names+=("Charlie")

保存文件并退出。

打印所有元素

为了确认数组包含预期的所有内容,可以一次性打印其中的全部元素。

在 Bash 中,访问数组变量的方式与普通变量略有不同。使用 ${array_name[@]} 可以展开所有元素。

  • @ 是一个特殊符号,表示「所有元素」。

${...} 形式也是参数展开的示例。Bash 不会直接按字面显示变量名,而是在 echo 获取最终文本之前,将数组展开为其中存储的元素。

打开 array_lab.sh:

nano array_lab.sh

添加打印命令:

## Print all elements in the array
echo "All Names: ${names[@]}"

保存文件并退出。

为脚本添加可执行权限,然后运行脚本:

chmod +x array_lab.sh
./array_lab.sh

结果:

All Names: Alice Bob Charlie

${names[@]} 被展开为数组中所有项目组成的、以空格分隔的列表。

遍历数组

打印整个列表有助于调试,但通常需要逐个处理项目。例如,你可能需要为列表中的每个名称创建一个用户账户。

为此,可以使用 for 循环。

打开 array_lab.sh:

nano array_lab.sh

在文件末尾添加循环:

echo "--- Processing Names ---"

## Loop through each item in the array
for name in "${names[@]}"; do
  echo "Hello, $name"
done

现在,完整脚本应如下所示:

#!/bin/bash

names=("Alice" "Bob")
names+=("Charlie")

echo "All Names: ${names[@]}"

echo "--- Processing Names ---"
for name in "${names[@]}"; do
  echo "Hello, $name"
done

保存文件并退出。运行脚本:

./array_lab.sh

结果:

为 "${names[@]}" 加上引号也很重要。这样可以将每个数组元素保留为独立项目;当值中包含空格时,这一点尤其重要。在实际脚本中,文件名和参数不一定只是由一个单词组成的简单字符串,因此这一细节更加重要。

All Names: Alice Bob Charlie
--- Processing Names ---
Hello, Alice
Hello, Bob
Hello, Charlie

循环从数组中逐个取出名称,将其赋值给变量 name,然后执行代码块。这是在 Bash 中处理列表最常见的方式。

总结

在本实验中,你学习了 Bash 数组的基础用法:

  1. 声明(name=(...)):使用初始值创建列表。
  2. 追加(+=):向现有数组动态添加新项目。
  3. 展开(${name[@]}):获取数组中的所有项目。
  4. 遍历(for):逐个处理列表中的项目。

对于需要高效处理多个文件、用户或数据项的脚本来说,数组是必不可少的工具。