骏马金龙 (新博客:www.junmajinlong.com)

网名骏马金龙,钟情于IT世界里的各种原理和实现机制,强迫症重症患者。爱研究、爱翻译、爱分享。特借此一亩三分田记录自己成长点滴!!!

SHELL脚本--shell数组基础

bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html


数组和变量的区别是:变量在内存中占用的空间是离散的,数组在内存中是先开辟一段连续的大内存空间,随后数组中的每个元素都放入数组内存中。数组元素使用数组index标识。

bash里有两种数组:普通数组和关联数组。普通数组只能使用整型数值作为数组索引,关联数组可以使用字符串作为索引。所谓的关联数组,它的另外三种称呼:字典(dict)、hash结构和映射(map),是一种key和value一 一对应的关系。

1.9.1 普通数组

定义数组的方式一:

[root@xuexi tmp]# array_test=(1 2 3 4)

它们分别存储在索引位0-3的位置上,是array_test[0]到array_test[3]对应的值。此时array_test[0]表示的是一个变量,所以使用$来引用。数组的引用方式:${array_name[index]}。

[root@xuexi tmp]# echo ${array_test[2]}
3

注意数组中定义是使用空格作为分隔符定义在括号内,而不是逗号。如果使用逗号,则它们将作为一个整体,也就是数组索引0的值。如果使用逗号,则:

[root@xuexi tmp]# array_test=(1,2,3,4)  

[root@xuexi tmp]# echo ${array_test[0]}   # 整体结果作为索引0位的值。
1,2,3,4 

定义数组的方式二:可以自定义索引位。

[root@xuexi tmp]# array_test1[1]=1
[root@xuexi tmp]# array_test1[2]=2
[root@xuexi tmp]# array_test1[3]=3
[root@xuexi tmp]# array_test1[4]=4
[root@xuexi tmp]# echo ${array_test1[*]}
1 2 3 4

但是在索引位4之后定义array_test1[7]=7则表示5和6的数组变量未定义,即不存在,这可以通过统计变量的元素个数来验证。但在shell中是可以直接引用未定义变量的,只不过它们的初始值是空或是0。

(1).打印数组所有值。

[root@xuexi tmp]# echo ${array_test1[*]}
1 2 3 4

或者使用@符号。

[root@xuexi tmp]# echo ${array_test1[@]}
1 2 3 4

(2).查看数组索引号。

[root@xuexi tmp]# echo ${!array_test1[*]}
1 2 3 4

或者

[root@xuexi tmp]# echo ${!array_test1[@]}
1 2 3 4

(3).数组中变量长度和数组长度。

[root@xuexi tmp]# echo ${#array_test1[1]}  # 显示下标为1的数组变量的字符长度

[root@xuexi tmp]# echo ${#array_test1[*]}  # 显示数组中的元素个数(只统计值不为空的元素)
4

[root@xuexi tmp]# echo ${#array_test1[@]}  # 显示数组中的元素个数(只统计值不为空的元素)
4

1.9.2 关联数组

关联数组支持字符串作为数组索引。使用关联数组必须先使用declare -A声明它。

[root@xuexi tmp]# declare -A array_dep   # 声明之后就可以给其赋值了

[root@xuexi tmp]# array_dep=([name1]=longshuai [name2]=xiaofang)

其中name1和name2就是关联数组的index。引用数组变量时需要使用index来引用对应的值。

[root@xuexi tmp]# echo ${array_dep[name1]}
longshuai

也可以分开赋值。

[root@xuexi tmp]# array_dep[name3]=zhangsan

[root@xuexi tmp]# array_dep[name4]=lisi

[root@xuexi tmp]# echo ${array_dep[name4]}
lisi

(1).查看数组所有值。

[root@xuexi tmp]# echo ${array_dep[*]}
zhangsan xiaofang longshuai lisi   # 可以看到是字母倒序排列的

或者:

[root@xuexi tmp]# echo ${array_dep[@]}
zhangsan xiaofang longshuai lisi

(2).查看数组索引号。

[root@xuexi tmp]# echo ${!array_dep[@]}   # 对应数组值的倒序排列
name3 name2 name1 name4

或者:

[root@xuexi tmp]# echo ${!array_dep[*]}
name3 name2 name1 name4

(3).统计数组长度。

[root@xuexi tmp]# echo ${#array_dep[*]}
4

或者:

[root@xuexi tmp]# echo ${#array_dep[@]}
4

1.9.3 数组元素截取、替换

和变量的截取和替换是类似的。

array=(1 2 3 4 5 6)
array0=${array[*]:2:2}   # 从数组全部元素中第2个元素向后截取2个元素出来(即3 4)
array1=${array[*]/5/6}   # 将数组中的5替换称6

还有从左匹配删除从右匹配删除,和变量是一样的。

array=(one two three foue five)

array1=${array[*]#*o}   # 从左非贪婪匹配并删除所有数组变量中匹配内容
array2=${array[*]##*o}  # 从左贪婪匹配并删除所有数组变量中匹配的内容
array2=${array[*]%o}    # 从右非贪婪匹配并删除所有数组变量中匹配内容
array2=${array[*]%%o}   # 从右贪婪匹配并删除所有数组变量中匹配内容

1.9.4 for循环遍历数组

在shell中的循环结构中,可以使用数组名来表示整个数组变量。

for i in ${array[*]};do  
    echo $i
done

或者让i变成数组index的方法:

for i in ${!array[*]};do
    echo ${array[$i]}
done

以下是遍历数组的三个常见用法总结:

array=($(ls /boot))

for i in ${array[*]};do  # 以数组值的方式直接遍历数组
    echo $i
done

for ((i=0;i<${#array[*]};i++));do    # 以数组变量个数的方式遍历数组
    echo ${array[$i]}
done

for i in ${!array[*]};do      # 以数组index的方式遍历数组
    echo ${array[$i]}
done

 以下是一个数组遍历的示例:统计文件中重复行的次数。假设a.log文件中内容如下。

[root@xuexi ~]# cat a.log
portmapper
portmapper
portmapper
portmapper
portmapper
portmapper
status
status
mountd
mountd
mountd
mountd
mountd
mountd
nfs
nfs
nfs_acl
nfs
nfs
nfs_acl
nlockmgr
nlockmgr
nlockmgr
nlockmgr
nlockmgr
nlockmgr

以下是数组遍历的脚本。

#!/bin/bash

declare -A array_test  # 定义关联数组
for i in `cat ~/a.log` do let ++array_test[$i] done for j in ${!array_test[*]} do printf "%-15s %3s\n" $j :${array_test[$j]} done

该脚本中第一个for循环中,以文件中内容做数组的index,每遍历到一个index就对该index进行数学运算的自加1操作。这一过程是遍历文件内容并为数组变量赋值的过程。

这样就得到如下结果:

array_test[status]=2
array_test[nfs]=4
array_test[portmapper]=6
array_test[nlockmgr]=6
array_test[nfs_acl]=2
array_test[mountd]=6

第二个for循环是将array_test数组中所有数组变量及其值取出来,这一步是遍历数组的过程。所以得到最终的结果:

[root@xuexi ~]# ./a.sh                 
status           :2
nfs              :4
portmapper       :6
nlockmgr         :6
nfs_acl          :2
mountd           :6
posted @ 2017-08-09 16:52  骏马金龙  阅读(6991)  评论(2编辑  收藏  举报