使用 Bash 中的关联数组掌控您的数据

关联数组允许您创建键值对列表,而不是仅仅编号的值。
76 位读者喜欢这篇文章。
bash logo on green background

Opensource.com

如果您曾经编写过代码,无论是 shell 脚本、Python 脚本、C++ 还是甚至 Scratch,那么您就会知道变量至关重要。计算机和程序员使用变量作为中转站,他们在其中偷偷地来回传递信息。例如,如果您需要在 shell 脚本中处理用户名,您可以设置一个变量,将用户名放入变量中,然后指示计算机对该变量执行某些操作(例如,对照授权用户列表检查它)。变量很重要,因为它们使代码能够动态:它们是信息的占位符,这些信息预计在您每次运行代码时都会更改。

但是变量,因为它们如此常见,也可能变得相当笨拙。通常,您在一个代码项目中收集了如此多的变量,以至于几乎不可能跟踪所有变量。您可以使用巧妙的约定,例如用通用字符串(user_name、user_pass、user_time 等)为所有相关变量添加前缀,或者您可以创建一个主列表将它们放在某处以便于参考,但是跟踪所有这些变量的开销可能会变得令人疲惫。

传统上,这个问题的一个答案是数组。这些在大多数编码语言(包括 Bash 等 shell 脚本语言)中都运行良好。

大多数 shell 都提供创建、操作和查询索引数组的能力。用简单的英语来说,索引数组是以数字为前缀的事物列表。这个事物列表以及它们分配的数字,方便地包装在一个变量中,这使得它很容易在您的代码中“携带”。

Bash,但是,包括创建关联数组的能力,并且它将这些数组视为任何其他数组。关联数组允许您创建键值对列表,而不是仅仅编号的值。

您可以将值分配给任意键

$ declare -A userdata
$ userdata[name]=seth
$ userdata[pass]=8eab07eb620533b083f241ec4e6b9724
$ userdata[login]=`date --utc +%s`

查询任何键

$ echo "${userdata[name]}"
seth
$ echo "${userdata[login]}"
1583362192

您可以从数组中期望的大多数常用数组操作都可用。例如,您可以列出所有值

$ echo "${userdata[*]}"
8eab07eb620533b083f241ec4e6b9724 seth 1583362192

您可以查看整个数组

$ typeset -A
declare -A BASH_ALIASES='()'
declare -A BASH_CMDS='()'
declare -A userdata='([pass]="8eab07eb620533b083f241ec4e6b9724" 
[name]="seth" 
[login]="1583362192" )'

您还可以使用 unset 命令从数组中删除项目

$ unset userdata[pass]
$ typeset -A
[...]
declare -A userdata='([name]="seth" 
[login]="1583362192" )'

最后,您可以移除整个数组。

$ unset "userdata[*]"

用于数据的数组

数组是用于将相关数据存储在一起的有用工具。在大多数情况下,您可以使用普通的变量,但有时将单个数据“对象”的属性存储在数组中更符合逻辑,以保持数据整合和索引。例如,如果您正在处理从 utmp 中获取的登录名和时间,那么将登录时间与该时间所指的用户关联起来会更有用,而不是仅仅将两个数据对象存储为没有明显连接的单独变量。

此外,与变量不同,数组中的条目不需要在您将数据存储在其中之前就存在。您不必确切知道在存储数据之前将要存储多少数据。如果您正在处理无法控制或预测的数据,这可能是一个很大的优势:如果您不知道从一天到另一天 utmp 中会期望有多少用户,那么很难构建一个脚本来包含所有条目。但是,使用数组,您只需声明一个数组并将数据读入其中,创建一个新的键值对,直到您用完要摄取的数据为止。

数组功能强大,并且在 Bash 以外的编程语言中也很常见。现在就开始使用它们吧!

接下来阅读什么

开始使用 Bash 编程

了解如何使用 Bash 编写自定义程序来自动化您的重复性任务。下载我们的新电子书开始使用。

标签
Seth Kenlon
Seth Kenlon 是一位 UNIX 极客、自由文化倡导者、独立多媒体艺术家和 D&D 爱好者。他曾在电影和计算机行业工作,通常同时进行。

1 条评论

非常好的发现,Seth!

© . All rights reserved.