一.基本介绍

1.awk:

  awk是一个强大的文本分析工具,在对文本文件的处理以及生成报表,awk是无可替代的。awk认为文本文件都是结构化的,它将每一个输入行定义为一个记录,行中的每个字符串定义为一个段,段和段之间使用分割符分割。


2.功能:流控制、数学运算、进程控制、内置的变量和函数、循环和判断


3.工作原理:

awk 会把每行进行一个拆分,用相应的命令对拆分出来的“段”进行处理。

(1)行工作模式,读入文件的每一行,会把一行的内容,存到$0里

(2)使用内置的变量FS(段的分隔符,默认用的是空白字符),分割这一行,把分割出来的每个段存到相应的变量$(1-100)

(3)输出的时候按照内置变量OFS(out FS),输出

(4)读入下一行继续操作

简单实例

[root@SERVER-Test testperl]# echo "this is a book" >./awk.txt
[root@SERVER-Test testperl]# awk '{print $2,$1,$3,$4}' awk.txt
is this a book

4.   Awk常用内置变量表:

1 $0             整个文本内容  

2 $1~$n          当前记录的第n个字段,字段间由FS分隔  

3 FS             输入字段分隔符 默认是空格  

4 OFS            输出字段分隔符 默认也是空格  

5 NF             统计当前正在处理行有多少字段个数,就是每行有多少列  

6 NR             记录已经读入处理的行数,从1开始(所有文件的读取的行数)

7 FNR            当前读取的文件已经处理的行数(所有文件中的一个文件)

7 RS             输入的记录分隔符,默认为换行符  

8 ORS            输出的记录分隔符,默认为换行符  

9 ARGC           命令行参数个数  

10 ARGV           命令行参数数组  

11 FILENAME       当前输入文件的名字  

12 IGNORECASE     如果为真,则进行忽略大小写的匹配  

13 ARGIND         当前被处理文件的ARGV标志符  

14 CONVFMT        数字转换格式 %.6g  

15 ENVIRON        UNIX环境变量  

16 ERRNO          UNIX系统错误消息  

17 FIELDWIDTHS    输入字段宽度的空白分隔字符串  

18 FNR            当前记录数  

19 OFMT           数字的输出格式 %.6g  

20 RSTART         被匹配函数匹配的字符串首  

21 RLENGTH        被匹配函数匹配的字符串长度  


二.print的简单使用

例:打印文本所有的数据): $0

[root@SERVER-Test testperl]# cp /etc/passwd pl
[root@SERVER-Test testperl]# awk -F : '{print $0}' pl
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

打印这个文本每行有多少列

[root@SERVER-Test testperl]# cat asd.txt
This is my cat
 my cat's name is betty
This is my dog
     my dog's name is frank
This is my fish
  my fish's name is george
This is my goat
  my goat's name is adam
[root@SERVER-Test testperl]# awk '{print NF}' asd.txt
4
5
4
5
4
5
4
5

例:打印每行的最后一个字段: $NF(也就是求asd.txt的$4这一列内容)

[root@SERVER-Test testperl]# cat asd.txt
This is my cat
 my cat's name is betty
This is my dog
     my dog's name is frank
This is my fish
  my fish's name is george
This is my goat
  my goat's name is adam
[root@SERVER-Test testperl]# awk '{print $NF}' asd.txt
cat
betty
dog
frank
fish
george
goat
adam

显示文本的一行中的第一个与第二个参数,中间可以加#号

[root@SERVER-Test testperl]# cat awk.txt
this is a book
[root@SERVER-Test testperl]# awk 'BEGIN{OFS="#"}{print $1,$2}' awk.txt
this#is

例:打印第三个字段: $3

[root@SERVER-Test testperl]# awk -F : '{print $3}' pl
0
1
2

例:打印第一行使用NR==1

[root@SERVER-Test testperl]# awk 'NR==1{print $0}' pl
root:x:0:0:root:/root:/bin/bash

例:打印最后一行

[root@SERVER-Test testperl]# awk -F : 'END{print $0}' pl
mockbuild:x:507:507::/home/mockbuild:/bin/bash

例:打印第一行第一个字段

[root@SERVER-Test testperl]# awk -F : 'NR==1{print $1}' pl
root

例:打印第一行最后一个字段

[root@SERVER-Test testperl]# awk -F : 'NR==1{print $NF}' pl
/bin/bash

例:打印最后一行最后一个字段

[root@SERVER-Test testperl]# awk -F : 'END{print $NF}' pl
/bin/bash

例:打印最后一行第一个字段

[root@SERVER-Test testperl]# awk -F : 'END{print $1}' pl
mockbuild

例:打印每行的倒数第二个字段,并在其后打印你好

[root@SERVER-Test testperl]# awk -F : '{print $(NF-1),"nihao"}' pl
/root nihao
/bin nihao
/sbin nihao

例:打印行号

[root@SERVER-Test testperl]# awk -F : '{print NR,$0}' pl
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin

例: 用:分割,删除第2个字段

[root@SERVER-Test testperl]# awk -F : 'BEGIN{FS=":";OFS=":"}{print $1,$3,$4,$5,$6,$7}' pl
root:0:0:root:/root:/bin/bash
bin:1:1:bin:/bin:/sbin/nologin

例如:显示文本中的参数,还可以加修饰符,还可以加字符串

[root@SERVER-Test testperl]# cat test.sh
this is a test zxc abc
[root@SERVER-Test testperl]# awk 'BEGIN{OFS="::"}{print $1"1234",$5,"hello"$6}' ./test.sh
this1234::zxc::helloabc

显示文本的一行中的第一个与第二个参数,中间可以加#号

[root@SERVER-Test testperl]# awk -F : 'BEGIN{OFS="#########"}{print $1,$5,$4}' ./passwd |head -2
root#########root#########0
bin#########bin#########1

输出三行,注意换行需要加\n

[root@SERVER-Test testperl]# awk 'BEGIN {print "line one\nline two\nline three"}'
line one
line two
line three

输出重定向>和>>

[root@SERVER-Test testperl]# awk -F : '{printf "%-10s%-15s\n", $1,$3 > "/root/testperl/1111.txt"}' /etc/passwd
[root@SERVER-Test testperl]# cat 1111.txt
root      0
bin       1
daemon    2
adm       3

例如:

[root@SERVER-Test testperl]# cat 1111.txt
root      0
bin       1
daemon    2
adm       3
lp        4
[root@SERVER-Test testperl]# awk -F: '{printf "%-10s%-15s\n", $1,$3 >> "/root/testperl/1111.txt"}' /etc/passwd
[root@SERVER-Test testperl]# cat 1111.txt
root      0
bin       1
daemon    2
adm       3
lp        4
root      0
bin       1
daemon    2
adm       3
lp        4
sync      5

自定义变量

例如:定义var=hello test

[root@SERVER-Test testperl]# awk -v var="hellow test" 'BEGIN {print var}'
hellow test

或者上面自定义也可以改成下面格式

[root@SERVER-Test testperl]# awk 'BEGIN {var="hello test";print var}'
hello test

四.awk的使用

(1)正则表达式

\(\)   \{\} 不支持

. * ^ $ ? + [] | \< \> ()  可以直接使用

~(匹配) !~(不匹配)

例:

[root@SERVER-Test testperl]# awk -F : '/^root/{print $1.$NF}' pl
root/bin/bash

例:

[root@SERVER-Test testperl]# awk -F : '!/^root/{print $1.$NF}' /etc/passwd | head -3
bin/sbin/nologin
daemon/sbin/nologin
adm/sbin/nologin

例:

[root@SERVER-Test testperl]# awk '/^$/{print "this is an empty line"}' ./passwd
this is an empty line
this is an empty line

例如:打印出第3列等于0,第7列匹配nologin的打印出来

[root@SERVER-Test testperl]# awk -F: '$3==0,$7~/nologin/ {print $1,$3,$7}' /etc/passwd
root 0 /bin/bash
bin 1 /sbin/nologin


例如:打印出第3列大于500的内容

[root@SERVER-Test testperl]# awk -F: '$3+1>500 {print $1,$3,$5}' /etc/passwd
www 500
mysql 501
redis 502
liweiguan 503
zabbix 504
elite 505
haojue 506
mockbuild 507

例如:打印出第7列匹配bash结尾的内容(~指匹配)

[root@SERVER-Test testperl]# awk -F: '$7~/bash$/ {print $1,$7}' /etc/passwd
root /bin/bash
redis /bin/bash
liweiguan /bin/bash
elite /bin/bash
haojue /bin/bash
mockbuild /bin/bash

例如:打印出第7列不匹配bash结尾的内容{ !~(不匹配)}

[root@SERVER-Test testperl]# awk -F: '$7!~"bash$" {print $1,$7}' /etc/passwd | head -5
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync

例如:对模式进行格式化操作

[root@SERVER-Test testperl]# awk -F: '$3==0,$7~/nologin/ {printf "%-10s%-15s%-20s\n", $1,$3,$7}' /etc/passwd
root      0              /bin/bash
bin       1              /sbin/nologin

如果我想添加表头,则需要添加GEGIN

[root@SERVER-Test testperl]# awk -F: 'BEGIN {print "Username  ID  SHELL"} {printf "%-10s%-15s%-20s\n", $1,$3,$7}' /etc/passwd | head -5
Username  ID  SHELL
root      0              /bin/bash
bin       1              /sbin/nologin
daemon    2              /sbin/nologin
adm       3              /sbin/nologin

当然也可以添加一个表的结尾

[root@SERVER-Test testperl]# awk -F: 'BEGIN {print "Username  Id  SHELL"} {printf "%-10s%-15s%-20s\n", $1,$3,$7} END {print "The report is end"}' /etc/passwd
Username  Id  SHELL
root      0              /bin/bash
bin       1              /sbin/nologin
daemon    2              /sbin/nologin
haojue    506            /bin/bash
mockbuild 507            /bin/bash
The report is end

Empty(空模式):匹配任意输入行,对文件中的每一行做匹配

例如:

[root@SERVER-Test testperl]# awk -F: '{printf "%-10s%-15s%-20s\n", $1,$3,$7}' /etc/passwd
root      0              /bin/bash
bin       1              /sbin/nologin
daemon    2              /sbin/nologin
adm       3              /sbin/nologin
lp        4              /sbin/nologin
sync      5              /bin/sync

(2)关系运算符

> < == != >= <=

例:找出匹配第三个字段等于0的

[root@SERVER-Test testperl]# awk -F : '$3==0{print $1,$2,$4,$5,$6,$7}' ./passwd
root x 0 root /root /bin/bash

例如:打印第三字段不等于0的,最后三行字符

[root@SERVER-Test testperl]# awk -F : '$3 !=0{print $1,$4,$5,$6,$7}' ./passwd | head -3
bin 1 bin /bin /sbin/nologin
daemon 2 daemon /sbin /sbin/nologin
adm 4 adm /var/adm /sbin/nologin

例如:打印第三个字段小于2的

[root@SERVER-Test testperl]# awk -F : '$3<2{print $1,$5,$7,$6}' ./passwd
root root /bin/bash /root
bin bin /sbin/nologin /bin

例如:过滤条件为:第三列的值为0 && 第6列的值为LISTEN

[root@SERVER-Test testperl]# cat netstat.txt
Proto Recv-Q Send-Q Local-Address          Foreign-Address             State
tcp        0      0 0.0.0.0:3306           0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:80             0.0.0.0:*                   LISTEN
tcp        0      0 127.0.0.1:9000         0.0.0.0:*                   LISTEN
tcp        0      0 coolshell.cn:80        124.205.5.146:18245         TIME_WAIT
tcp        0      0 coolshell.cn:80        61.140.101.185:37538        FIN_WAIT2
tcp        0      0 coolshell.cn:80        110.194.134.189:1032        ESTABLISHED
tcp        0      0 coolshell.cn:80        123.169.124.111:49809       ESTABLISHED
tcp        0      0 coolshell.cn:80        116.234.127.77:11502        FIN_WAIT2
tcp        0      0 coolshell.cn:80        123.169.124.111:49829       ESTABLISHED
tcp        0      0 coolshell.cn:80        183.60.215.36:36970         TIME_WAIT
tcp        0   4166 coolshell.cn:80        61.148.242.38:30901         ESTABLISHED
tcp        0      1 coolshell.cn:80        124.152.181.209:26825       FIN_WAIT1
tcp        0      0 coolshell.cn:80        110.194.134.189:4796        ESTABLISHED
tcp        0      0 coolshell.cn:80        183.60.212.163:51082        TIME_WAIT
tcp        0      1 coolshell.cn:80        208.115.113.92:50601        LAST_ACK
tcp        0      0 coolshell.cn:80        123.169.124.111:49840       ESTABLISHED
tcp        0      0 coolshell.cn:80        117.136.20.85:50025         FIN_WAIT2
tcp        0      0 :::22                  :::*                        LISTEN
[root@SERVER-Test testperl]# awk '$3==0 && $6=="LISTEN"' netstat.txt
tcp        0      0 0.0.0.0:3306           0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:80             0.0.0.0:*                   LISTEN
tcp        0      0 127.0.0.1:9000         0.0.0.0:*                   LISTEN
tcp        0      0 :::22                  :::*                        LISTEN

其中的“==”为比较运算符。其他比较运算符:!=, >, <, >=, <=

[root@SERVER-Test testperl]# awk '$3>0{print $0}' netstat.txt
Proto Recv-Q Send-Q Local-Address          Foreign-Address             State
tcp        0   4166 coolshell.cn:80        61.148.242.38:30901         ESTABLISHED
tcp        0      1 coolshell.cn:80        124.152.181.209:26825       FIN_WAIT1
tcp        0      1 coolshell.cn:80        208.115.113.92:50601        LAST_ACK

如果我们需要表头的话,我们可以引入内建变量NR,再加上格式化输出。

[root@SERVER-Test testperl]# awk '$3==0 && $6=="LISTEN" || NR==1 {printf "%-20s %-20s %s\n",$4,$5,$6}' netstat.txt
Local-Address        Foreign-Address      State
0.0.0.0:3306         0.0.0.0:*            LISTEN
0.0.0.0:80           0.0.0.0:*            LISTEN
127.0.0.1:9000       0.0.0.0:*            LISTEN
:::22                :::*                 LISTEN

3)逻辑运算符

&& || !

与 或 非

例:

[root@SERVER-Test testperl]# awk -F : '$3>0 && $3<10' ./passwd | head -5
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@SERVER-Test testperl]# awk -F : '$3>0 && $3<10 {print $1,$2,$5,$4}' ./passwd | head -5
bin x bin 1
daemon x daemon 2
adm x adm 4
lp x lp 7
sync x sync 0

例:

[root@SERVER-Test testperl]# awk -F : '$3>0 || $3<10 {print $1,$2,$5,$4}' ./passwd | head -4
root x root 0
bin x bin 1
daemon x daemon 2
adm x adm 4

(4)算数运算符

+ - * / %(取模(余数)) ^(幂运算)

例:输出名字,总成绩,平均成绩

[root@SERVER-Test testperl]# cat 123
zx 23 98 78
cv 89 99 78
bn 34 89 98
[root@SERVER-Test testperl]#  awk '{print $1,$2+$3+$4,($2+$3+$4)/3}' 123
zx 199 66.3333
cv 266 88.6667
bn 221 73.6667


[root@SERVER-Test testperl]# awk '{printf"%-5s %4d %.2f\n",$1,$2+$3+$4,($2+$3+$4)/3}' 123
zx     199 66.33
cv     266 88.67
bn     221 73.67

(5)BEGIN  END

BEGIN{ 动作;动作;... }  在处理文件之前,要执行的动作;只执行一次

END{ 动作;动作;... }    在处理完文件之后,要执行的动作;只执行一次

BEGIN :可以给文件添加标题、定义变量、定义文件的分隔符

END:汇总的操作

getline可以从管道和标准输入读取输入,然后传递给变量。

[root@SERVER-Test testperl]# awk 'BEGIN {"date" | getline ab}{print}END{print ab}' 123
zx 23 98 78
cv 89 99 78
bn 34 89 98
2014年 03月 31日 星期一 13:26:16 CST
[root@SERVER-Test testperl]# cat 123
zx 23 98 78
cv 89 99 78
bn 34 89 98

四.awk的模式:

常见的模式类型:

1、Regexp: 正则表达式,格式为/regular expression/

例如:显示以r开头的行 。

[root@SERVER-Test testperl]# awk -F: '/^r/{print $1,$3,45,$7}' /etc/passwd
root 0 45 /bin/bash
redis 502 45 /bin/bash

2、expresssion:表达式,其值非0或为非空字符时满足条件,如:$1 ~ /foo/ 或 $1 == "magedu",用运算符~(匹配)和~!(不匹配

例如:显示id号小于等于5的用户和id号

[root@SERVER-Test testperl]# awk -F: '$3<=5{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5

取出默认shell为bash的用户        

[root@SERVER-Test testperl]# awk -F: '$7~"bash$"{print $1,$7}' /etc/passwd
root /bin/bash
redis /bin/bash
liweiguan /bin/bash
elite /bin/bash
haojue /bin/bash
mockbuild /bin/bash

显示默认shell不是bash的用户        

[root@SERVER-Test testperl]# awk -F: '$7!~/bash$/{print $1,$7}' /etc/passwd
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync

3、Ranges: 指定的匹配范围,格式为pat1,pat2

例如:显示id号为0或者shell为/sbin/nologin的用户        

[root@SERVER-Test testperl]# awk -F: '$3==0,$7~/nologin/ {print $1,$3,$7}' /etc/passwd
root 0 /bin/bash
bin 1 /sbin/nologin

4、BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次

[root@SERVER-Test testperl]# awk -F: '$3==0,$7~/nologin$/ {printf "%-10s%-20s\n", $1,$5,$7}' /etc/passwd
root      root     
bin       bin

例如:可以在显示时显示表头

[root@SERVER-Test testperl]# awk -F: 'BEGIN{print "Username SHELL"} {printf "%-10s%-20s\n", $1,$3,$7}' /etc/passwd
Username SHELL
root      0        
bin       1        
daemon    2

也可以显示表头和表尾

[root@SERVER-Test testperl]# awk -F: 'BEGIN{print "Username SHELL"} {printf "%-10s%-20s\n", $1,$5,$7} END{print "The report is End"}' /etc/passwd
Username SHELL
root      root     
bin       bin      
daemon    daemon   
The report is End

5、Empty(空模式):匹配任意输入行,对文件中的每一行做匹配

[root@SERVER-Test testperl]# awk -F: '{printf "%-10s%-20s\n", $1,$5,$7}' /etc/passwd
root      root     
bin       bin      
daemon    daemon   
adm       adm      
lp        lp       
sync      sync

常见的Action(动作)

/正则表达式/:使用通配符的扩展集。

关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。

模式匹配表达式:指定一个行的范围。该语法不能包括BEGIN和END模式。

BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作

END:在最后一条输入记录被读取之后发生的动作。

五.awk里的流控制和循环

(1)简单的条件判断

语法:(表达式 ? 值1 : 值2) 如果表达式成立,输出值1;否则输出值2

[root@SERVER-Test testperl]# cat 123
2 8 9 4
7 5 7 3
3 7 5 9
[root@SERVER-Test testperl]# awk '{print ($1>$2 ? $1:$2)}' 123
8
7
7

例:

[root@SERVER-Test testperl]# cat 123
2 8 9 4
7 5 7 3
3 7 5 9
[root@SERVER-Test testperl]# awk '{print ($2<$3 ? $2:$3)}' 123
8
5
5

(2)if判断

语法:if (表达式) {动作1} else {动作2} 如果表达式成立,那么执行动作

例:若用户是root则显示“admin”否则显示为“Common user”

[root@SERVER-Test testperl]# awk -F : '{if ($1=="root") print$1,"admin"; else print $1,"common user"}' /etc/passwd
root admin
bin common user
daemon common user

可以对上面的语法格式化了,这样看起来更美观    

[root@SERVER-Test testperl]# awk -F: '{if ($1=="root") printf "%-15s; %s\n", $1,"admin"; else printf "%-15s: %s\n", $1,"Common User"}' /etc/passwd
root           ; admin
bin            : Common User
daemon         : Common User

统计id号大于等于500的用户个数,这里的-v是进行赋值操作。

[root@SERVER-Test testperl]# awk -F: -v sum=0 '{if ($3>=500) sum++} END{print sum}' /etc/passwd
8

  例

[root@SERVER-Test testperl]# cat 123
zx 90 98 34
cv 98 80 89
bn 88 87 90
[root@SERVER-Test testperl]# awk '{if ($2>=80 && $2<=100) {print $1,"great"} else {print $1,"good"}}' 123
zx great
cv great
bn great

(2)多支判断

{

if (表达式)

{ 动作1;动作2;...}

else if (表达式)

{ 动作1;动作2;...}

else if (表达式)

{ 动作1;动作2;...}

......

else

{ 动作1;动作2;...}

}

例如:

判断的标准:

90-100 A

80-89  B

70-79  C

60-69  D

0-59   E

[root@SERVER-Test testperl]# awk '{if ($2>=90 && $2<=100) {print $1,"A"} else if ($2>=80 && $2<90) {print $1."B"} else if ($2>=70 && $2<80) {print $1,"C"} else if ($2>=60 && $2<70) {print $1,"D"} else {print $1,"E"}}' 123
tx A
tx1B
tx2 C
tx3B
tx4 C
tx5 C
[root@SERVER-Test testperl]# cat 123
tx 90 86 86
tx1 89 78 85
tx2 79 80 85
tx3 80 70 60
tx4 75 85 65
tx5 78 62 80

(3)循环while

语法:'var=初值;while (表达式){动作1;...更新变量的动作;}'

例如:显示字符串大于等于8的(每一个字符串都要做一下判断)

[root@SERVER-Test testperl]# awk -F: '{i=1;while (i<=NF) {if (length($i)>=8) {print $i};i++}}' /etc/passwd/bin/bash
/sbin/nologin
/sbin/nologin
/var/adm
/sbin/nologin

显示字符串大于等于4的        

[root@SERVER-Test testperl]# awk -F: '{i=1;while (i<=NF) {if (length($i)>=4) {print $i}; i++}}' /etc/passwd
root
root
/root
/bin/bash

例如:

[root@SERVER-Test testperl]# awk -F : '{var=1; while (var<=NF) {print $var;var++}}' ./passwd | head -5
root
x
0
0
root

例如

[root@SERVER-Test testperl]# awk -F : '{var=NF; while (var>=2) {print $var ":";var--};print $1}' ./passwd | head -5
/bin/bash:
/root:
root:
0:
0:

例如:显示字符串大于等于8的(每一个字符串都要做一下判断)

[root@SERVER-Test testperl]# awk -F : '{i=1;while (i<=NF) {if (length($i)>=8) {print $i}; i++}}' ./passwd | head -5
/bin/bash
/sbin/nologin
/sbin/nologin
/var/adm
/sbin/nologin

do-while语句

例如:其实上面语句也可以这样做,显示字符串大于等于8的(注意使用do语句使,先执行的是条件)

[root@SERVER-Test testperl]# awk -F: '{i=1;do {print $i;i++} while (i>=8)}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
uucp
operator
games

(4)for循环

语法:

{

for(表达式)

{动作1;...}

}

表达式:分为3部分:

(1)初始化表达式 i=1

(2)测试表达式   i<10

(3)更新测试表达式 i++

语句:

next 处理输入行的下一个输入行

exit 退出

continue 结束本次循环

break 跳出循环

例如:显示字符串大于等于4的        

[root@SERVER-Test testperl]# awk -F: '{for(i=1;i<=NF;i++) {if (length($i)>=4) {print $i}}}' /etc/passwd
root
root
/root
/bin/bash

显示字符串小于等于4的

[root@SERVER-Test ~]# awk -F: '{for(i=1;i<NF;i++) {if (length($i)<5) {print $i}}}' /etc/passwd
root
x
0
0
root

例如:打印每一行的前4列

[root@SERVER-Test ~]# awk -F: '{for (i=1;i<=4;i++) print $i}' /etc/passwd
root
x
0
0
bin
x
1
1
daemon

六.awk中使用数组

array[index-expression]

index-expression可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array的方式。要遍历数组中的每一个元素,需要使用如下的特殊结构:

for (var in array) { statement1, ... }

其中,var用于引用数组下标,而不是元素值;

例如:显示各个shell的个数和

[root@SERVER-Test testperl]# awk -F: '{shell[$NF]++}END{for(A in shell) {print A,shell[A]}}' /etc/passwd
/sbin/shutdown 1
/bin/bash 6
/sbin/nologin 28
/sbin/halt 1
/bin/sync 1


例如:统计tcp连接状态的个数($6也是最后一个字段,可以使用$NF)        

# netstat -ant | awk '/^tcp/ {STATE[$NF]++} END {for(a in STATE) print a, STATE[a]}'
LISTEN 11
ESTABLISHED 2

每出现一次被/^tcp/模式匹配到的行,数组S[$NF]就加1,NF为当前匹配到的行的        

最后一个字段,此处用其值做为数组S的元素索引;    


例如:统计访问本地的IP及个数        

# awk '{count[$1]++}END{for(ip in count) {printf "%-20s:%d\n",ip,count[ip]}}'
/var/log/httpd/access_log
192.168.10.1      :1
172.16.50.5       :10

用法与上一个例子相同,用于统计某日志文件中IP地的访问量          


看几个小例子:

#从file文件中找出长度大于80的行

awk 'length>80' file

#按连接数查看客户端IP

netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr


参考:

http://whluwit.blog.51cto.com/2306565/1438156 

http://coolshell.cn/articles/9070.html

http://tanxin.blog.51cto.com/6114226/1222140

http://my.oschina.net/denglz/blog/151310

http://www.178linux.com/48228 

视频:http://edu.51cto.com/lesson/id-17380.html