awk数组
简介:
数组
数组: 一个个元素按一定顺序排列的集合。
把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为数组下标。
组成数组的各个变量称为数组的分量,也叫数组的元素,有时也称为 下标变量。
在awk中数组叫关联数组因为下标记可以是数也可以是串。awk中的数组不必提前声明,也不必声明大小。数组元素用 0或空串来初始化,这根据上下文而定。
一.定义方法
1.用数值作数组索引(下标)
array[1]="Tom" array[2]="Jerry"
2.用字符串做数组索引(下标)
array_test["one"]="Hello World" array_test["two"]="This is the cat"
使用:
使用${array_name[@]} 或者 ${array_name[*]} 都可以全部显示数组中的元素 同样${#array_name[@]} 或者 ${#array_name[*]}都可以用来求数组的长度
3.打印数组
[root@host ~]# awk 'BEGIN{array[1]="Tom";array[2]="Jerry";for(key in array) print key,array[key]}' 1 Tom 2 Jerry [root@host test]# awk 'BEGIN{arr[1]="tom";arr[2]="jerry";} END{for(key in arr) print key,arr[key]}' /etc/hosts 1 tom 2 jerry
BEGIN和END区别:

是给程序赋予初始状态 和 在程序结束之后执行一些扫尾的工作。
任何在BEGIN之后列出的操作(在{}内)将在awk开始扫描输入之前执行,而END之后列出
的操作将在扫描全部的输入之后执行。通常使用BEGIN来显示变量和预置(初始化)变量,
使用END来输出最终结果。
4. awk脚本

[root@host test]# cat t.awk #!/bin/awk BEGIN{ arr[1]="tom" arr[2]="jerry" for(key in arr) print key,arr[key] } [root@host test]# awk -f t.awk 1 tom 2 jerry 转为命令行: [root@host test]# awk 'BEGIN{arr[1]="tom";arr[2]="jerry";for(key in arr) print key,arr[key]}' 1 tom 2 jerry
5.把文件内容第一列作为下标k,第二列作为值S[k],放入数组S[],然后输出

a. [root@host test]# cat /etc/passwd |awk 'BEGIN{arr[1]="tom";arr[2]="jerry";} END{for(key in arr) print key,arr[key]}' > t.log [root@host test]# cat t.log 1 tom 2 jerry [root@host test]# awk '{S[$1]=$2}END{for(k in S) print k,S[k]}' t.log 1 tom 2 jerry b. [root@host test]# cat t1.log 1 ABC 2 QWE [root@host test]# awk '{S[$1]=$2}END{for(k in S) print k,S[k]}' t1.log 1 ABC 2 QWE
例1:处理文件内容,将域名取出并根据域名进行计数排序处理

dom.log http://www.tomcat.org/index.html http://www.tomcat.org/1.html http://post.tomcat.org/index.html http://mp3.tomcat.org/index.html http://www.tomcat.org/3.html http://post.tomcat.org/2.html 方法1: [root@host test]# cut -d / -f3 dom.log |sort -r |uniq -c 3 www.tomcat.org 2 post.tomcat.org 1 mp3.tomcat.org 方法2: [root@host test]# awk -F / '{print $3}' dom.log |sort -r |uniq -c 3 www.tomcat.org 2 post.tomcat.org 1 mp3.tomcat.org 方法3: [root@host test]# awk -F "/" '{S[$3]++} END{for(k in S) print k,S[k]}' dom.log |sort -rn -k2 |head #选此 www.tomcat.org 3 post.tomcat.org 2 mp3.tomcat.org 1
例2.统计体重报表

[root@host test]# cat test.txt 001 name Tom 100kg 002 name Jerry 80kg 003 name Hon 111kg 004 name Dii 80kg 005 name Rain 80kg 006 name Yom 100kg 方法1 [root@C1 monitor_man]# awk '{S[$4]++} END{for(a in S) print a,S[a]}' t.sh 100kg 2 111kg 1 80kg 3 方法2 [root@host test]# awk '/^00/ {++S[$NF]} END {for (a in S) print a,S[a]}' test.txt 100kg 2 80kg 3 111kg 1 #提示: key=100kg S[100kg]=2 key=80kg S[80kg]=3 key=111kg S[111kg]=1
例3:统计Apache日志单ip访问请求数排名

[root@host test]# cat a.log 10.0.0.41 - - [03/Dec/2010:23:27:01 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.43 - - [03/Dec/2010:23:27:01 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.42 - - [03/Dec/2010:23:27:01 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.46 - - [03/Dec/2010:23:27:02 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.42 - - [03/Dec/2010:23:27:02 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.47 - - [03/Dec/2010:23:27:02 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.41 - - [03/Dec/2010:23:27:02 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.47 - - [03/Dec/2010:23:27:02 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.41 - - [03/Dec/2010:23:27:03 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.46 - - [03/Dec/2010:23:27:03 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 方法1: [root@host test]# awk '{++S[$1]} END{for(key in S) print key,S[key]}' a.log |sort -rn -k2 10.0.0.41 3 10.0.0.47 2 10.0.0.46 2 10.0.0.42 2 10.0.0.43 1 提示:$1为第一个域的内容。-k2 为对第二个字段排序,即对数量排序。 方法2: [root@host test]# awk '{print $1}' a.log|sort|uniq -c|sort -rn -k1 3 10.0.0.41 2 10.0.0.47 2 10.0.0.46 2 10.0.0.42 1 10.0.0.43 提示:简单易用 方法3: [root@host test]# sed 's/- -.*$//g' a.log|sort|uniq -c|sort -rn -k1 3 10.0.0.41 2 10.0.0.47 2 10.0.0.46 2 10.0.0.42 1 10.0.0.43 提示:sed管道后的第一个sort是让所有一样的IP挨着,因为uniq -c只能对相邻的IP行去重计数
例4:查看状态连接数

[root@master ~]# netstat -n |awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 命令拆分: /^tcp/ 过滤出以tcp开头的行 S[] 定义了 S 数组,在awk中,数组下标通常从 1 开始,而不是 0。 NF 当前记录里域个数,默认以空格分隔,如上所示的记录,NF域个数等于6 $NF 表示一行的最后一个域的值,如上所示的记录,$NF也就是$6,表示第6个字段的值,也就是SYN_RECV或TIME_WAIT等。 S[$NF] 表示数组元素的值,如上所示的记录,就是S[TIME_WAIT]状态的连接数 ++S[$NF] 表示把某个数加一,如上所示的记录,就是把S[TIME_WAIT]状态的连接数加 1
awk例子:
https://blog.51cto.com/oldboy/1184177