shell数组和awk数组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell数组和awk数组相关的知识,希望对你有一定的参考价值。

awk终于能入门了,所以整理了该文章,内容大多来自网上。


一、bash支持一维数组(不支持多维数组),没有限定数组的大小。在shell中,用括号来表示数组,数组元素用空格符号分割开。类似于C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0


1. 定义数组
数组名array,元素a b c
[[email protected]~]# array=(a b c)

2.获取所有元素
[[email protected]~]# echo ${array[*]}
a b c
[[email protected]~]# echo ${array[@]}
a b c

3.获取数组的长度
[[email protected]~]# echo ${#array[*]}
3

4.通过下标0 1 2依次获取数组的每一个元素
[[email protected]~]# echo ${array[0]}
a
[[email protected]~]# echo ${array[1]}
b
[[email protected]~]# echo ${array[2]}
c

5.获取部分数组
[[email protected]~]# echo ${array[*]:0:2}
a b

6.删除第一个元素
[[email protected]~]# unset array[0]

7.删除整个数组
[[email protected]~]# unset array


小例子:

#!/bin/bash
#删除指定目录下的文件

a=(/usr/local/tomcat/logs /home/user/tomcat/logs /usr/local/app/tomcat/logs)

for i in "${a[@]}"
do 
    find "$i" -maxdepth 1 -type f -name "*.txt"  ! -name "*.*" ! -mtime +30 -exec rm {} \;
done


二、awk数组

awk的数组,一种关联数组(Associative Arrays),支持多维数组,下标可以是数字和字符串。因无需对数组名和元素提前声明,也无需指定元素个数 ,所以awk的数组使用非常灵活。


1.建立数组

array[index]=value 数组名array,下标index以及相应的值value


2.读取数组值

{for (item in array)  print array[item]} # 输出的顺序是随机的
{for(i=1;i<=len;i++)  print array[i]}    # len 是数组的长度


3.多维数组,array[index1,index2,……]:SUBSEP是数组下标分割符。可以事先设定SUBSEP,也可以直接在SUBSEP的位置输入你要用的分隔符,如:

[[email protected]~]# awk ‘BEGIN{array["a","b"]=1;for(i in array) print i}‘
a b
[[email protected]~]# awk ‘BEGIN{SUBSEP=":";array["a","b"]=1;for(i in array) print i}‘
a:b
[[email protected]~]# awk ‘BEGIN{array["a"":""b"]=1;for(i in array) print i}‘
a:b
[[email protected]~]# cat file 
A 192.168.1.1 HTTP 
B 192.168.1.2 HTTP 
B 192.168.1.2 mysql 
C 192.168.1.1 MYSQL 
C 192.168.1.1 MQ 
D 192.168.1.4 nginx
[[email protected]~]# awk ‘{a[$1"-"$2]++}END{for(i in a)print a[i],i}‘ file
[[email protected]~]# awk ‘{SUBSEP="-"}{a[$1,$2]++}END{for(i in a) print a[i],i}‘ file
2 B-192.168.1.2
1 D-192.168.1.4
2 C-192.168.1.1
1 A-192.168.1.1


4.删除数组或数组元素,使用delete函数

delete array                 #删除整个数组
delete array[item]           #删除某个数组元素(item)


5.排序:awk中的asort函数可以实现对数组的值进行排序,不过排序之后的数组下标改为从1到数组的长度。在gawk 3.1.2以后的版本还提供了一个asorti函数,这个函数不是依据关联数组的值,而是依据关联数组的下标排序,即asorti(array)以后,仍会用数字(1到数组长度)来作为下标,但是array的数组值变为排序后的原来的下标,除非你指定另一个参数如:asorti(a,b)。

[[email protected]~]# echo ‘aa
bb
aa
bb
cc‘ |awk ‘{a[$0]++}END{l=asorti(a);for(i=1;i<=l;i++)print a[i]}‘
aa
bb
cc
 
[[email protected]~]# echo ‘aa
bb
aa
bb
cc‘ |awk ‘{a[$0]++}END{l=asorti(a,b);for(i=1;i<=l;i++)print b[i],a[b[i]]}‘
aa 2
bb 2
cc 1


[[email protected]~]# echo "a
1
0
b
2
10
8
100" |
awk ‘{a[$0]=$0} #建立数组a,下标为$0,赋值也为$0
END{
len=asort(a)      #利用asort函数对数组a的值排序,同时获得数组长度len
for(i=1;i<=len;i++) print i "\t"a[i]  #打印
}‘
1       0
2       1
3       2
4       8
5       10
6       100
7       a
8       b


6.去重

[[email protected]~]# cat file 
1
2
1
3
4
5
6
[[email protected]~]# awk ‘a[$1]++‘ file
1
[[email protected]~]# awk ‘!a[$1]++‘ file
1
2
3
4
5
6


7.求和

[[email protected]~]# echo "aaa 1
aaa 1
ccc 1
aaa 1
bbb 1
ccc 1" |awk ‘{a[$1]+=$2}END{for(i in a) print i,a[i]}‘
aaa 3
bbb 1
ccc 2


8.通过split函数建立数组:数组的下标为从1开始的数字

split(s, a [, r]) # s:string, a:array name,[,r]:regular expression。
[[email protected]~]# echo ‘abcd‘ |awk ‘{len=split($0,a,"");for(i=1;i<=len;i++) print "a["i"] = " a[i];print "length = " len}‘
a[1] = a
a[2] = b
a[3] = c
a[4] = d
length = 4

 

求1月份相同名字和总和

[[email protected]~]# cat file 
Tom     2012-12-11      car     5       3000
John    2013-01-13      bike    4       1000
vivi    2013-01-18      car     4       2800
Tom     2013-01-20      car     3       2500
John    2013-01-28      bike    6       3500
[[email protected]~]# awk ‘{split($2,a,"-");if(a[2]==01){b[$1]+=$5}}END{for(i in b)print i,b[i]}‘ file 
vivi 2800
Tom 2500
John 4500


9.求平均数

[[email protected]~]# cat file 
/circlelistbytjid,耗时:25ms
/circlelistbytjid,耗时:24ms
/circlelistbytjid,耗时:21ms
/circlelistbytjid,耗时:13ms
/circlelistbytjid,耗时:25ms
/circlelistbytjid,耗时:13ms
/circlelistbytjid,耗时:23ms
/circlelistbytjid,耗时:24ms
[[email protected]~]# awk -F: ‘{a+=+$2}END{print a/NR}‘ file
21


10.求最大值

获取数字字段最大值

[[email protected]~]# cat file 
a b 1 
c d 2 
e f 3 
g h 3 
i j 2
[[email protected]~]# awk ‘BEGIN{max=0}{if($3>max)max=$3}END{print max}‘ file
3


打印第三字段最大行

[[email protected]~]# awk ‘BEGIN{max=0}{a[$0]=$3;if($3>max)max=$3}END{for(v in a)if(a[v]==max)print v}‘ file
e f 3 
g h 3


11.合并file1和file2,除去重复项

[[email protected]~]#cat file1
aaa
bbb
ccc
ddd
[[email protected]~]#cat file2
aaa
eee
ddd
fff


[[email protected]~]# awk ‘NR==FNR{a[$0]=1;print}   #读取file1,建立数组a,下标为$0,并赋值为1,然后打印
NR>FNR{                   #读取file2
if(!(a[$0])) {print }      #如果file2 的$0不存在于数组a中,即不存在于file1,则打印。
}‘ file1 file2
aaa
bbb
ccc
ddd
eee
fff


提取文件1中有,但文件2中没有:

[[email protected]~]# awk ‘NR==FNR{a[$0]=1}           #读取file2,建立数组a,下标为$0,并赋值为1
NR>FNR{                   #读取file1
if(!(a[$0])) {print }      #如果file1 的$0不存在于数组a中,即不存在于file2,则打印。
}‘ file2 file1
bbb
ccc


参考文章:http://bbs.chinaunix.net/thread-2312439-1-2.html


本文出自 “卡卡西” 博客,请务必保留此出处http://whnba.blog.51cto.com/1215711/1891360

以上是关于shell数组和awk数组的主要内容,如果未能解决你的问题,请参考以下文章

Linux13 shell函数数组及awkawk中的数组

关于awk数组的问题、

如何在linux Shell脚本里面把一个数组传递到awk内部进行处理

awk

shell脚本,awk数组之如何处理多个文件。

shell (awk)数组使用案例