标签:shell和awk数组
awk终于能入门了,所以整理了该文章,内容大多来自网上。
一、bash支持一维数组(不支持多维数组),没有限定数组的大小。在shell中,用括号来表示数组,数组元素用空格符号分割开。类似于C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0
1. 定义数组 数组名array,元素a b c [root@localhost~]# array=(a b c) 2.获取所有元素 [root@localhost~]# echo ${array[*]} a b c [root@localhost~]# echo ${array[@]} a b c 3.获取数组的长度 [root@localhost~]# echo ${#array[*]} 3 4.通过下标0 1 2依次获取数组的每一个元素 [root@localhost~]# echo ${array[0]} a [root@localhost~]# echo ${array[1]} b [root@localhost~]# echo ${array[2]} c 5.获取部分数组 [root@localhost~]# echo ${array[*]:0:2} a b 6.删除第一个元素 [root@localhost~]# unset array[0] 7.删除整个数组 [root@localhost~]# 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的位置输入你要用的分隔符,如:
[root@localhost~]# awk ‘BEGIN{array["a","b"]=1;for(i in array) print i}‘ a b [root@localhost~]# awk ‘BEGIN{SUBSEP=":";array["a","b"]=1;for(i in array) print i}‘ a:b [root@localhost~]# awk ‘BEGIN{array["a"":""b"]=1;for(i in array) print i}‘ a:b
[root@localhost~]# 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 [root@localhost~]# awk ‘{a[$1"-"$2]++}END{for(i in a)print a[i],i}‘ file [root@localhost~]# 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)。
[root@localhost~]# 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 [root@localhost~]# 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
[root@localhost~]# 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.去重
[root@localhost~]# cat file 1 2 1 3 4 5 6 [root@localhost~]# awk ‘a[$1]++‘ file 1 [root@localhost~]# awk ‘!a[$1]++‘ file 1 2 3 4 5 6
7.求和
[root@localhost~]# 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。
[root@localhost~]# 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月份相同名字和总和
[root@localhost~]# 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 [root@localhost~]# 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.求平均数
[root@localhost~]# cat file /circlelistbytjid,耗时:25ms /circlelistbytjid,耗时:24ms /circlelistbytjid,耗时:21ms /circlelistbytjid,耗时:13ms /circlelistbytjid,耗时:25ms /circlelistbytjid,耗时:13ms /circlelistbytjid,耗时:23ms /circlelistbytjid,耗时:24ms [root@localhost~]# awk -F: ‘{a+=+$2}END{print a/NR}‘ file 21
10.求最大值
获取数字字段最大值
[root@localhost~]# cat file a b 1 c d 2 e f 3 g h 3 i j 2 [root@localhost~]# awk ‘BEGIN{max=0}{if($3>max)max=$3}END{print max}‘ file 3
打印第三字段最大行
[root@localhost~]# 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,除去重复项
[root@localhost~]#cat file1 aaa bbb ccc ddd [root@localhost~]#cat file2 aaa eee ddd fff [root@localhost~]# 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中没有:
[root@localhost~]# 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数组
原文地址:http://whnba.blog.51cto.com/1215711/1891360