数组简介

在bash脚本编程当中,变量是存储单个元素的内存空间;而数组是存储多个元素的一段连续的内存空间。

数组由数组名和下标构成,如下。

ARRAY_NAME[SUBSCRIPT]

数组按照下标的类型可分为两种:

  • 索引(indexed)数组:下标为0、1、2等非负整数。
  • 关联(associative)数组:下标为用户自定义的字符串。

数组的操作

声明

索引数组可以不声明直接使用;而关联数组如果不声明直接使用的话,会被认为是索引数组,即使它的下标是字符串。

索引数组的声明方式。

# declare -a ARRAY_NAME

关联数组的声明方式。

# declare -A ARRAY_NAME

赋值

一次只赋值一个元素。

# ARRAY_NAME[SUBSCRIPT]=VALUE

一次赋值全部元素。

# ARRAY_NAME = ("VAL1" "VAL2" "VAL3" ...)

一次赋值多个可以是不连续的元素。

# ARRAY_NAME = ([] = "VAL1" [] = "VAL3")

像这种不要求元素必须依次存在的数组(即可以在没有A[1]和A[2]的时候就赋值A[3]),叫做稀疏格式数组。因此,bash支持稀疏格式的数组。

读取标准输入赋值数组。

# read -a ARRAY_NAME

在输入的时候,以空格作为元素的分隔符,以回车键结束元素的赋值。

向数组的末尾追加元素。

ARRAY_NAME[${#ARRAY_NAME[@]}]=VALUE 

或者

ARRAY_NAME+=(VALUE)

引用

引用单个数组元素。

${ARRAY_NAME[SUBSCRIPT]}

如果省略SUBSCRIPT,那么就等同于SUBSCRIPT=0。即以下两个引用是相同的。

${ARRAY_NAME[]}
${ARRAY_NAME}

下标可以是一个变量,当下标是一个变量的时候,可以省略掉展开下标变量字符“$”。即${array[$var]}=${array[var]}。

[root@c7-server ~]# declare -a name=(bu jing yun)
[root@c7-server ~]# echo ${name[*]}
bu jing yun
[root@c7-server ~]# declare -i a= b= c=
[root@c7-server ~]# echo ${name[$a]}
bu
[root@c7-server ~]# echo ${name[$b]}
jing
[root@c7-server ~]# echo ${name[$c]}
yun
[root@c7-server ~]# echo ${name[a]}
bu
[root@c7-server ~]# echo ${name[b]}
jing
[root@c7-server ~]# echo ${name[c]}
yun

引用数组的所有元素。正常情况下,二者没有区别,只有当被双引号包裹的时候,“@”被展开为每个元素为一个独立的单词;“*”被展开为所有元素为一个统一的单词。

${ARRAY_NAME[@]}
${ARRAY_NAME[*]}

引用数组元素的长度。

${#ARRAY_NAME[SUBSCRIPT]}

引用数组的长度,即数组的元素个数。

${#ARRAY_NAME[@]}
${#ARRAY_NAME[*]}

引用数组的部分元素(切片)。

${ARRAY_NAME[@]:OFFSET:NUMBER}
${ARRAY_NAME[*]:OFFSET:NUMBER}

OFFSET:偏移,表示偏移/跳过数组中的前几个元素。

NUMBER:表示偏移后取几个元素。

如果省略了NUMBER,并且OFFSET的值为“ -n”(注意,-n的左边有空格),则表示引用倒数的n个元素。

截止目前我们引用的都是数组的值,如果我们想引用数组的下标的话,可以使用:

${!ARRAY_NAME[@]}
${!ARRAY_NAME[*]}

删除

删除数组元素。

# unset ARRAY_NAME[SUBSCRIPT]

删除数组。

# unset ARRAY_NAME

数组示例

定义一个索引数组,逐一赋值数组元素。

[root@c7-server ~]# declare -a my_array
[root@c7-server ~]# my_array[]=zhang
[root@c7-server ~]# my_array[]=wen
[root@c7-server ~]# my_array[]=long

根据数组下标获取数组元素。留意我们上文说的,当引用数组不带下标的时候,等同于引用${ARRAY_NAME[0]}。

[root@c7-server ~]# echo ${my_array}
zhang
[root@c7-server ~]# echo ${my_array[]}
zhang
[root@c7-server ~]# echo ${my_array[]}
wen
[root@c7-server ~]# echo ${my_array[]}
long

引用数组中的所有元素,顺便测试一下“@”和“*”的区别。注意,这个区别,仅在${my_array[@]}或者${my_array[*]}被双引号包裹的情况下才会出现。

[root@c7-server ~]# echo ${my_array[@]}
zhang wen long
[root@c7-server ~]# echo ${my_array[*]}
zhang wen long
[root@c7-server ~]# for i in "${my_array[@]}"; do echo $i; done
zhang
wen
long
[root@c7-server ~]# for i in "${my_array[*]}"; do echo $i; done
zhang wen long

引用数组个数。

[root@c7-server ~]# echo ${#my_array[@]}

[root@c7-server ~]# echo ${#my_array[*]}

引用数组中元素的个数。

[root@c7-server ~]# echo ${my_array[]}
zhang
[root@c7-server ~]# echo ${#my_array[]}

接下来演示其他几种不同的赋值方式,操作前可先删除数组。

[root@c7-server ~]# unset my_array
[root@c7-server ~]# my_array=([]=zhang []=wen []=long)
[root@c7-server ~]# echo ${my_array[@]}
zhang wen long
[root@c7-server ~]# unset my_array
[root@c7-server ~]# read -a my_array
Mon Tue Wed Thu Fri Sat Sun
[root@c7-server ~]# echo ${my_array[@]}
Mon Tue Wed Thu Fri Sat Sun

数组元素去子串(substring),即切片。

[root@c7-server ~]# echo ${my_array[@]}
Mon Tue Wed Thu Fri Sat Sun
[root@c7-server ~]# echo ${my_array[@]::}
Thu Fri
[root@c7-server ~]# echo ${my_array[@]::}
Wed Thu Fri
[root@c7-server ~]# echo ${my_array[@]: -}
Fri Sat Sun

数组元素追加。

[root@c7-server ~]# echo ${my_array[@]}
Mon Tue Wed Thu Fri Sat Sun
[root@c7-server ~]# my_array+=(ddd)
[root@c7-server ~]# my_array[${#my_array[@]}]=eee
[root@c7-server ~]# echo ${my_array[@]}
Mon Tue Wed Thu Fri Sat Sun ddd eee

引用数组的下标(subscript)。个人感觉引用数组下标在关联数组中比较有用,在索引数组中用处不大。

[root@c7-server ~]# echo ${!my_array[@]}

[root@c7-server ~]# unset my_array
[root@c7-server ~]# declare -A my_array
[root@c7-server ~]# my_array=([name]=zwl [age]= [sex]=male)
[root@c7-server ~]# echo ${my_array[@]}
zwl male
[root@c7-server ~]# echo ${!my_array[@]}
name age sex

练习题

题一:生成10个100以内的非负整数并存入数组当中,对其进行排序然后输出最大值和最小值。

这道题,涉及到算法中的冒泡排序,可以参考一下《冒泡排序_百度百科》中的概念解释,以及《1.1 冒泡排序 | 菜鸟教程》中的图示,这个GIF图真的超棒!

按照升序排序后,最大值和最小值取头尾即可。

代码示例。

#!/bin/bash

declare -a rand
declare -i rand_length var
for i in {..}; do
rand[$i]=$((RANDOM%))
done
echo -e "The original array is \t${rand[*]}."
rand_length=${#rand[*]}
#echo $rand_length for i in $(seq $((rand_length-)) | sort -nr); do
for((j=;j<$i;j++)); do
if [ ${rand[j]} -gt ${rand[((j+))]} ]; then
var=${rand[j]}
rand[j]=${rand[j+]}
rand[j+]=$var
fi
done
#echo ${rand[*]}
done echo -e "The last array is \t${rand[*]}."
echo "The min of the array is ${rand[0]}."
echo "The max of the array is ${rand[-1]}."

结果演示。

[root@c7-server ~]# bash arrayBubbleSort.sh
The original array is .
The last array is .
The min of the array is .
The max of the array is .
[root@c7-server ~]# bash arrayBubbleSort.sh
The original array is .
The last array is .
The min of the array is .
The max of the array is .
[root@c7-server ~]# bash arrayBubbleSort.sh
The original array is .
The last array is .
The min of the array is .
The max of the array is .

看懂代码以后,我们可以调整一下echo语句,就可以看到每次循环排序的结果。

The original array is              .

10 21 34 36 50 52 57 68 83 98

从结果中我们也会发现,除非是刚好是倒序的情况,否则在循环的中途就可以排序完成了。

这个脚本,个人觉得还是会稍微难点的,尤其是对于算法基础薄弱且非编程的人员,我也是Google后才知道结果的,真的搞不懂的同学,不必纠结,将来再补算法即可,这篇随笔主要是了解数组的。

题二:定义一个数组,数组元素为/var/log/目录下所有以.log结尾的文件的文件名;统计下标为偶数的文件的行数并求和。

#!/bin/bash

declare -a filePool=(/var/log/*.log)
declare -i sum=0
declare -i line for i in $(seq 0 $((${#filePool[*]}-1))); do
if [ $((i%2)) -eq 0 ]; then
line=$(wc -l ${filePool[i]} | cut -d " " -f 1)
((sum+=line))
fi
done echo "The sum of lines which meet the conditions is $sum."

Bash脚本编程之数组的更多相关文章

  1. 高级bash脚本编程(三)

    高级bash脚本编程 知识点 compound 和 comparison -a 逻辑与 exp1 -a exp2 如果表达式 exp1 和 exp2 都为真的话,那么结果为真. -o 逻辑或 exp1 ...

  2. 高级Bash脚本编程(一)

    高级Bash脚本编程 Bash 它是能力很强的计算机语言,被称为解释性语言或脚本语言,它可以调用所有的UNIX命令和工具再加上公共程序. Bash中的特殊字符 注释(#) (除#!外,#!是用于指定当 ...

  3. Bash脚本编程总结

    bash脚本编程之用户交互: read [option]… [name …]  -p ‘PROMPT’  -t TIMEOUT bash -n /path/to/some_script  检测脚本中的 ...

  4. Bash脚本编程之字符串处理

    简介 其实这里说得字符串处理,对应的是bash官网中的[Shell Parameter Expansion],不过直接去看这部分内容实在是太难以理解了.就按照马哥所说的字符串处理会比较好理解,平常使用 ...

  5. SHELL脚本编程-普通数组(列表)和关联数组(字典)

    SHELL脚本编程-普通数组(列表)和关联数组(字典) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数组相关概述 变量: 存储单个元素的内存空间 数组: 存储多个元素的连续的 ...

  6. 脚本命令高级Bash脚本编程指南(31):数学计算命令

    题记:写这篇博客要主是加深自己对脚本命令的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢. 高等Bash脚本编程指南(31):数学盘算命令 成于坚持,败于止步 操作数字 factor ...

  7. 高级Bash脚本编程指南(27):文本处理命令(三)

    高级Bash脚本编程指南(27):文本处理命令(三) 成于坚持,败于止步 处理文本和文本文件的命令 tr 字符转换过滤器. 必须使用引用或中括号, 这样做才是合理的. 引用可以阻止shell重新解释出 ...

  8. 高级Bash脚本编程指南《Advanced Bash-Scripting Guide》 in Chinese

    <Advanced Bash-Scripting Guide> in Chinese <高级Bash脚本编程指南>Revision 10中文版 在线阅读链接:http://ww ...

  9. 高级Bash脚本编程(二)

    高级Bash脚本编程(二) 退出 退出状态码 退出:exit 被用来结束一个脚本,它也返回一个值,并且这个值会传递给脚本的父进程,父进程会使用这个值做下一步的处理. 每个命令都会返回一个退出状态码,成 ...

随机推荐

  1. 前端WEB编辑器最爱——webstrom

    欲先善其事,必先利其器,如题.看到网上一篇介绍webstrom的文章,觉得功能确实强大,也知道为什么阿里巴巴的前端传到github上的文件为啥都有一个 .idea 文件,(传说淘宝内部推荐写js用we ...

  2. Jeewx-Boot 1.1 版本发布,基于SpringBoot的开源微信管家系统

    项目介绍 JeewxBoot是一款基于SpringBoot的开源微信管家系统,采用SpringBoot2.1.3 + Mybatis + Velocity 框架技术.支持微信公众号.微信第三方平台(扫 ...

  3. 移动端touch滑动事件监听

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  4. expect脚本同步文件、expect脚本指定host和要同步的文件、构建文件分发系统、批量远程执行命令

    7月20日任务 20.31 expect脚本同步文件20.32 expect脚本指定host和要同步的文件20.33 构建文件分发系统20.34 批量远程执行命令扩展:shell多线程 http:// ...

  5. c语言作业07

    问题 答案 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-2/homework/8655 我在 ...

  6. phpStudy搭建PHP服务器

    目录 1 下载 2 安装 3 新建站点 4 配置host phpStudy是一个PHP调试环境的程序集成包. 该程序包集成最新的 Apache+Nginx+LightTPD PHP MySQL+php ...

  7. shell du sh 文件大小输出

    按照文件大小升序输出结果: du -sh * | sort -h 如果要逆序输出,则: du -sh * | sort -hr

  8. luogu P2701 [USACO5.3]巨大的牛棚Big Barn |动态规划

    题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N x N 的方格.输入数据中包括有树的 ...

  9. 谈架构设计中DDD思想的运用

    首先,描述一下我的业务场景及项目分层结构,非标准DDD(其实我不觉得有标准),只是思考的时候有带入DDD思想. 业务场景:这是一个ERP系统对中台提供的接口项目,仓储操作大多都是存储过程去完成的. 项 ...

  10. [TimLinux] Python 再谈装饰器

    参考链接:https://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators 1. 函数对象 能 ...