Linux shell编程学习笔记15:定义数组、获取数组元素值和长度

一、 Linux shell 脚本编程中的数组概述

数组是一种常见的数据结构。跟大多数编程语言一样,大多数Linux shell脚本支持数组,但对数组的支持程度各不相同,比如数组的维度,是支持一维数组还是多维数组?再如,数组元素的下标是从 0 开始还是从1开始?则因shell而异,下面我们以zsh、sh、bash为例来讲解。

二、数组的定义

在Linux shell脚本编程中,定义数组有两种方法。

(一)数组名=(数值1 数值2 ...... 数值n)

数值之间用空格间隔。

实例:

1.在zsh中

(1)在命令行定义

csdn @ edu in ~ [21:37:32]

$ ++a=(1 'a' b)++

csdn @ edu in ~ [21:37:42]

$ ++echo $a++

1 a b

我们首先用命令 ++a=(1 'a' b)++定义了数组a

然后用命令 ++echo $a++显示数组a 的元素。

(2)在脚本文件中定义

csdn @ edu in ~ [22:20:47] C:1

$ ++echo 'a=(1 'a' b)' > a.sh++

csdn @ edu in ~ [22:21:31]

$ ++echo 'echo $a' >> a.sh++

csdn @ edu in ~ [22:21:48]

$ ++cat a.sh++

a=(1 a b)

echo $a

csdn @ edu in ~ [22:21:51]

$ ++source ./a.sh++

1 a b

csdn @ edu in ~ [22:22:01]

$

在上面的实例中,我们首先使用使用echo + 输出重定向方式将数组定义语句 ++echo 'a=(1 'a' b)' > a.sh++ 写入脚本文件 a.sh

然后 将 显示数组a元素的命令 ++echo 'echo $a' >> a.sh++写入脚本文件 a.sh

接下来我们使用cat命令查看脚本文件 a.sh的内容:

a=(1 a b)

echo $a

最后,我们使用命令 ++source ./a.sh++ 执行脚本文件a.sh

注意,在上面创建的脚本文件 a.sh中,我们没有在第一行写入shebang或hashbang语句来指定脚本解释器。

2.在sh中

(1)在命令行定义

[csdn ~]$ exec sh

sh-4.2$ a=(1 'a' b)

sh-4.2$ echo $a

1

sh-4.2$

(2)在脚本文件中定义

sh-4.2$ echo 'a=(1 'a' b)' > a.sh

sh-4.2$ echo 'echo $a' >> a.sh

sh-4.2$ cat a.sh

a=(1 a b)

echo $a

sh-4.2$ . a.sh

sh: .: a.sh: file not found

sh-4.2$ source ./a.sh

1

sh-4.2$

3.在bash中

(1)在命令行定义

csdn @ edu in ~ [23:27:45] C:127

$ ++exec bash++

[csdn ~]$ ++echo $0++

bash

[csdn ~]$ ++a=(1 'a' b)++

[csdn ~]$ ++echo $a++

1

[csdn ~]$

在bash中,数组同样创建起来了,与上面不同的是,命令 echo $a 只显示了数组中的第1个元素,而不是所有元素。

(2)在脚本文件中定义

[csdn ~]$ echo 'a=(1 'a' b)' > a.sh

[csdn ~]$ echo 'echo $a' >> a.sh

[csdn ~]$ cat a.sh

a=(1 a b)

echo $a

[csdn ~]$ . a.sh

1

[csdn ~]$

与上面的在命令行定义数组一样,bash中的命令 echo $a 只显示了数组中的第1个元素,而不是所有元素。

(二)数组名[下标]=数值

1.在zsh中

(1)在命令行定义

csdn @edu in ~ ++b[0]=0++

zsh: b: assignment to invalid subscript range

csdn @edu in ~ ++b[1]=1++

csdn @edu in ~ ++b[2]=a++

csdn @edu in ~ ++echo $b++

1 a

csdn @edu in ~

在上面的例子中,我们首先尝试直接在命令行定义数组元素:++b[0]=0++,但是zsh提示下标超出范围。

接下来,我们的命令 ++b[1]=1++ 和 ++b[2]=a++ 顺利完成,最后我们用命令 ++echo $b++显示 数组b的2个元素值:1 a。

可见,在zsh中,数组元素的下标是从1开始的。

(2)在脚本文件中定义

$ ++echo 'b[0]=0' > b.sh++

csdn @ edu in ~ [22:07:01]

$ ++echo 'b[1]=1' >> b.sh++

csdn @ edu in ~ [22:07:24]

$ ++echo 'b[2]=a' >> b.sh++

csdn @ edu in ~ [22:07:39]

$ ++echo 'echo $b' >> b.sh++

csdn @ edu in ~ [22:08:05]

$ ++cat b.sh++

b[0]=0

b[1]=1

b[2]=a

echo $b

csdn @ edu in ~ [22:08:17]

$ ++source ./b.sh++

./b.sh:1: b: assignment to invalid subscript range

csdn @ edu in ~ [22:08:27] C:126

$ ++bash ./b.sh++

0

csdn @ edu in ~ [22:08:53]

$

接着我们使用echo + 输出重定向方式将数组定义语句

b[0]=0

b[1]=1

b[2]=a

写入脚本文件b.sh

然后 我们将 显示数组元素 的命令 ++echo 'echo $b' >> b.sh++写入脚本文件b.sh

随后我们使用命令 ++cat b.sh++ 查看脚本文件b.sh 的内容:

b[0]=0

b[1]=1

b[2]=a

echo $b

接下来我们使用命令 ++source ./b.sh++来执行脚本文件b.sh,但是命令在zsh下出错了:

./b.sh:1: b: assignment to invalid subscript range

这再次说明,在zsh中,数组元素的下标是从1开始的。

最后我们使用命令 ++bash ./b.sh++ 来执行脚本,命令顺利完成。

可见,在bash 中,数组元素的下标是从0开始的。

2.在sh中

(1)在命令行中定义

csdn @edu in ~ ++exec sh++

sh-4.2$ ++b[0]=0++

sh-4.2$ ++b[1]=1++

sh-4.2$ ++b[2]=a++

sh-4.2$ ++echo $b++

0

sh-4.2$

数组成功创建,但只看到了数组中的第1个元素值。

(2)在脚本文件中定义

sh-4.2$ echo 'b[0]=0' > b.sh

sh-4.2$ echo 'b[1]=1' >> b.sh

sh-4.2$ echo 'b[2]=a' >> b.sh

sh-4.2$ echo 'echo $b' >> b.sh

sh-4.2$ cat b.sh

b[0]=0

b[1]=1

echo $b

sh-4.2$ source ./b.sh

0

sh-4.2$

我们先使用echo + 输出重定向方式将数组定义语句

b[0]=0

b[1]=1

b[2]=a

写入脚本文件b.sh

然后 我们将 显示数组元素 的命令 ++echo 'echo $b' >> b.sh++写入脚本文件b.sh

随后我们使用命令 ++cat b.sh++ 查看脚本文件b.sh 的内容:

b[0]=0

b[1]=1

b[2]=a

echo $b

最后我们使用 ++source ./b. sh++ 命令来执行脚本文件b.sh,数组成功创建,但只看到了数组中的第1个元素值。

3.在bash中

(1)在命令行中定义

csdn @ edu in ~ [23:53:42]

$ exec bash

[csdn ~]$ echo $0

bash

[csdn ~]$ b[0]=0

[csdn ~]$ b[1]=1

[csdn ~]$ b[2]=a

[csdn ~]$ echo $b

0

[csdn ~]$

命令全部顺利执行,可见在bash中,数组元素的下标是从0开始的,但echo $b只显示了数组第1个元素值。

(2)在脚本文件中定义

[csdn ~]$ echo b[0]=0 > b.sh

[csdn ~]$ echo b[1]=1 >> b.sh

[csdn ~]$ echo b[2]=a >> b.sh

[csdn ~]$ echo 'echo $b' >> b.sh

[csdn ~]$ cat b.sh

b[0]=0

b[1]=1

b[2]=a

echo $b

[csdn ~]$ . b.sh

0

[csdn ~]$

在脚本文件中执行跟 命令行执行结果是一样的。

(三)小结

在zsh中,数组元素的下标是从 1 开始的,使用"$数组名" 可以获得数组所有元素值。

在sh和bash中,数组元素的下标是从 0 开始的,使用"$数组名" 只能获得数组第1个元素值。

三、获取所有的数组元素

通过上面的实例,我们发现在sh和bash中,使用"$数组名" 只能获得数组第1个元素值,那么如何获取所有的数组元素呢?我们可以使用* 或 @ 作为下标来获取,具体格式即:

${数组名[@]}

${数组名[*]}

(一)zsh中

csdn @ edu in ~ [12:24:50]

$++echo $0++

/bin/zsh

csdn @ edu in ~ [12:25:24]

$ ++a=(1 2 'a')++

csdn @ edu in ~ [12:25:42]

$ ++echo $a++

1 2 a

csdn @ edu in ~ [12:27:06]

$ ++echo ${a[@]}++

1 2 a

csdn @ edu in ~ [12:27:39]

$ ++echo ${a[*]}++

1 2 a

csdn @ edu in ~ [12:32:40]

$

(二)在sh中

csdn @ edu in ~ [12:32:40]

$ ++exec sh++

sh-4.2$ a=(1 2 'a')

sh-4.2$ ++echo $a++

1

sh-4.2$ ++echo ${a[@]}++

1 2 a

sh-4.2$ ++echo ${a[*]}++

1 2 a

sh-4.2$

(三)在bash中

sh-4.2$ ++exec bash++

[csdn ~]$ ++a=(1 2 'a')++

[csdn ~]$ ++echo $a++

1

[csdn ~]$ ++echo ${a[@]}++

1 2 a

[csdn ~]$ ++echo ${a[*]}++

1 2 a

[csdn ~]$

四、获取数组或数组元素的长度

在介绍字符串时,我们说过获取字符串的格式是:${#字符串名},获取数组或数组元素长度的格式是相似的:

${#数组名[下标]}

${#数组名[下标]}

如果要取数组的长度,那么下标就用*或 @。如果要取数组某个元素的长度,那么下标就用元素的下标。

(一)在zsh中

csdn @ edu in ~ [12:57:21]

$ ++echo $0++

/bin/zsh

csdn @ edu in ~ [12:57:24]

$ ++b[1]=1++

csdn @ edu in ~ [12:57:31]

$ ++b[2]=22++

csdn @ edu in ~ [12:57:36]

$ ++echo ${b[*]}++

1 22

csdn @ edu in ~ [12:57:49]

$ echo ${#b[*]}

2

csdn @ edu in ~ [12:57:55]

$ ++echo ${#b[@]}++

2

csdn @ edu in ~ [12:57:59]

$ echo ${b[0]}

csdn @ edu in ~ [12:58:07]

$ echo ${#b[0]}

0

csdn @ edu in ~ [12:58:11]

$ echo ${b[1]}

1

csdn @ edu in ~ [12:58:26]

$ echo ${#b[1]}

1

csdn @ edu in ~ [12:58:30]

$ echo ${b[2]}

22

csdn @ edu in ~ [12:58:35]

$ echo ${#b[2]}

2

(二)sh中

csdn @ edu in ~ [13:07:28]

$ ++exec sh++

sh-4.2$ ++b[1]=1++

sh-4.2$ ++b[2]=22++

sh-4.2$ ++echo ${b[*]}++

1 22

sh-4.2$ ++echo ${#b[*]}++

2

sh-4.2$ ++echo ${#b[@]}++

2

sh-4.2$ echo ++${b[0]}++

sh-4.2$ echo ++${#b[0]}++

0

sh-4.2$ echo ++${b[1]}++

1

sh-4.2$ echo ++${#b[1]}++

1

sh-4.2$ echo ++${b[2]}++

22

sh-4.2$ echo ++${#b[2]}++

2

sh-4.2$

(三)bash中

[csdn ~]$ b[1]=1

[csdn ~]$ b[2]=22

[csdn ~]$ echo ${b[@]}

1 22

[csdn ~]$ echo ${#b[@]}

2

[csdn ~]$ echo ${#b[*]}

2

[csdn ~]$ echo ${b[0]}

[csdn ~]$ echo ${#b[0]}

0

[csdn ~]$ echo ${b[1]}

1

[csdn ~]$ echo ${#b[1]}

1

[csdn ~]$ echo ${b[2]}

22

[csdn ~]$ echo ${#b[2]}

2

[csdn ~]$

在上面的实例中,由于zsh中数组元素下标是从1开始的,所以我们定义数组b时,是从下标为1 的元素开始的。

然后我们先获取整个数组的元素值和长度,然后从下标0开始获取数组每个元素的值和长度。

值得注意的是,我们使用命令 echo ${b[0]} 尝试显示数组b中下标为0 的元素值 时,系统没有提示出错;使用命令echo ${#b[0]}尝试显示数组b中下标为0 的元素的长度时,系统反馈为0。

相关推荐
一坨阿亮13 分钟前
Linux 使用中的问题
linux·运维
dsywws1 小时前
Linux学习笔记之vim入门
linux·笔记·学习
幺零九零零2 小时前
【C++】socket套接字编程
linux·服务器·网络·c++
一个通信老学姐3 小时前
专业130+总400+武汉理工大学855信号与系统考研经验电子信息与通信工程,真题,大纲,参考书。
考研·信息与通信·信号处理·1024程序员节
小林熬夜学编程3 小时前
【Linux系统编程】第四十一弹---线程深度解析:从地址空间到多线程实践
linux·c语言·开发语言·c++·算法
力姆泰克4 小时前
看电动缸是如何提高农机的自动化水平
大数据·运维·服务器·数据库·人工智能·自动化·1024程序员节
力姆泰克4 小时前
力姆泰克电动缸助力农业机械装备,提高农机的自动化水平
大数据·服务器·数据库·人工智能·1024程序员节
程思扬4 小时前
为什么Uptime+Kuma本地部署与远程使用是网站监控新选择?
linux·服务器·网络·经验分享·后端·网络协议·1024程序员节
sun0077004 小时前
拷贝 cp -rdp 和 cp -a
linux·运维·服务器
wowocpp4 小时前
ubuntu 22.04 server 安装 anaconda3
linux·运维·ubuntu