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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/120434.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis为什么变慢了

一、Redis为什么变慢了 1.Redis真的变慢了吗? 对 Redis 进行基准性能测试 例如,我的机器配置比较低,当延迟为 2ms 时,我就认为 Redis 变慢了,但是如果你的硬件配置比较高,那么在你的运行环境下,可能延迟是 0.5ms 时就可以认为 Redis 变慢了。 所以,你只有了解了你的…

蓝桥杯每日一题2023.10.27

题目描述 快速排序 - 蓝桥云课 (lanqiao.cn) #include <stdio.h>int quick_select(int a[], int l, int r, int k) {int p rand() % (r - l 1) l;int x a[p];{int t a[p]; a[p] a[r]; a[r] t;}int i l, j r;while(i < j) {while(i < j && a[i] &…

Python轮廓追踪【OpenCV形态学操作】

文章目录 概要代码运行结果 概要 一些理论知识 OpenCV形态学操作理论1 OpenCV形态学操作理论2 OpenCV轮廓操作|轮廓类似详解 代码 代码如下&#xff0c;可以直接运行 import cv2 as cv# 定义结构元素 kernel cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) # print kern…

【Linux】rpm和yum的使用

不知道是不是有和我一样的宝子们&#xff0c;在rpm上卡了老久老久&#xff0c;但其实搞通了&#xff0c;理解了原理之后&#xff0c;不难的&#xff0c;所以不管你现在遇到的困难是什么&#xff0c;都不要放弃&#xff0c;一定要坚持&#xff0c;加油。 一、rpm 1.rpm rpm的…

On Moving Object Segmentation from Monocular Video with Transformers 论文阅读

论文信息 标题&#xff1a;On Moving Object Segmentation from Monocular Video with Transformers 作者&#xff1a; 来源&#xff1a;ICCV 时间&#xff1a;2023 代码地址&#xff1a;暂无 Abstract 通过单个移动摄像机进行移动对象检测和分割是一项具有挑战性的任务&am…

使用vue-cli搭建spa项目,vue项目结构说明,开发示例,如何修改端口号

目录 1. vue-cli安装 1.1 安装前提 1.2 什么是vue-cli 1.3 安装vue-cli 2. 使用vue-cli构建项目 2.1 使用脚手架创建项目骨架 2.2 到新建项目目录&#xff0c;安装需要的模块 2.3 如何修改端口号 2.4 添加element-ui模块 2.5 package.json详解 3. install命令中的-g…

目标检测技术概述

什么是目标检测&#xff1f; 在计算机视觉众多的技术领域中&#xff0c;目标检测&#xff08;Object Detection&#xff09;也是一项非常基础的任务&#xff0c;图像分割、物体追踪、关键点检测等通常都要依赖于目标检测。在目标检测时&#xff0c;由于每张图像中物体的数量、…

云游数智农业世界,体验北斗时空智能

今日&#xff0c;2023年中国国际农业机械展览会在武汉正式拉开帷幕&#xff0c;众多与会者云集&#xff0c;各类农机产品纷呈&#xff0c;盛况空前。 千寻位置作为国家北斗地基增强系统的建设与运营方&#xff0c;在中国国际农业机械展览会上亮相&#xff0c;以「北斗时空智能 …

代码审计及示例

简介&#xff1a; 代码安全测试是从安全的角度对代码进行的安全测试评估。 结合丰富的安全知识、编程经验、测试技术&#xff0c;利用静态分析和人工审核的方法寻找代码在架构和编码上的安全缺陷&#xff0c;在代码形成软件产品前将业务软件的安全风险降到最低。 方法&#x…

合成数据的好处和用途

在不断变化的数据科学和人工智能环境中&#xff0c;合成数据集的概念成为具有多种用途的强大工具。 假设您是一名数据科学家&#xff0c;并分配了为电子商务网站创建尖端推荐系统的任务。为此&#xff0c;您需要大量的用户交互数据。但是&#xff0c;您面临着保护用户隐私和处…

Lua入门使用与基础语法

文章目录 目的基础说明开发环境基础语法注释数据类型变量流程控制函数 总结 目的 Lua是一种非常小巧的脚本语言&#xff0c;基于C构建并且完全开源&#xff0c;可以方便的嵌入到各种项目中&#xff0c;当然也可以单独使用。Lua经常被用在很多非脚本语言的项目中&#xff0c;用…

设计模式—创建型模式之单例模式

设计模式—创建型模式之单例模式 介绍 单例模式说明&#xff1a;一个单一的类&#xff0c;负责创建自己的对象&#xff0c;同时确保系统中只有单个对象被创建。 单例模式特点&#xff1a; 某个类只能有一个实例&#xff1b;&#xff08;构造器私有&#xff09;它必须自行创…

Redis 主从

目录 ​编辑一、构建主从架构 1、集群结构 2、准备实例和配置 &#xff08;1&#xff09;创建目录 &#xff08;2&#xff09;修改原始配置 &#xff08;3&#xff09;拷贝配置文件到每个实例目录 &#xff08;4&#xff09;修改每个实例的端口&#xff0c;工作目录 &a…

虹科分享 | 买车无忧?AR带来全新体验!

文章来源&#xff1a;虹科数字化与AR 阅读原文&#xff1a;https://mp.weixin.qq.com/s/XsUFCTsiI4bkEMBHcGUT7w 新能源汽车的蓬勃发展&#xff0c;推动着汽车行业加速进行数字化变革。据数据显示&#xff0c;全球新能源汽车销售额持续上升&#xff0c;预计到2025年&#xff0…

MySQL初始化之后启动报错(mysqld: Table ‘mysql.plugin‘ doesn‘t exist)

报错场景 初始化之后&#xff0c;服务无法启动。错误日志error-log 报错如下&#xff1a;&#xff08;mysql库下的系统表不存在&#xff09; 2023-10-26T06:03:08.150163-00:00 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started. 2023-10-26T06:03:08.496…

javascript原生态xhr上传多个图片,可预览和修改上传图片为固定尺寸比例,防恶意代码,加后端php处理图片

//前端上传文件 <!DOCTYPE html> <html xmlns"http://www.w3.org/1999/xhtml" lang"UTF-8"></html> <html><head><meta http-equiv"Content-Type" content"text/html;charsetUTF-8;"/><title…

关于前端如何下载后端接口返回content-type为application/octet-stream的文件

关于前端如何下载后端接口返回response-type为application/octet-stream的文件 问题描述 后端接口定义为直接返回一个文件&#xff0c;如果带认证信息可以直接通过浏览器url下载&#xff0c;但是接口需要传headers认证信息&#xff0c;url上又不支持传相关信息 解决 前端…

p5.js map映射

本文简介 带尬猴&#xff0c;我嗨德育处主任 p5.js 为开发者提供了很多有用的方法&#xff0c;这些方法实现起来可能不难&#xff0c;但却非常实用&#xff0c;能大大减少我们的开发时间。 本文将通过举例说明的方式来讲解 映射 map() 方法。 什么是映射 从 p5.js 文档 中可…

N-129基于springboot,vue学生宿舍管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vuevue-element-admin 服务端技术&#xff1a;springboot,mybatis…