天天看點

awk:報告生成器

awk:報告生成器

格式化後顯示資訊

文法:

awk [options] 'script' file1 file2, ...

awk [options] 'PARTTERN { action }' file1 file2, ...

最常見的action:print,printf

awk的基本特征:

a.每一次取一行

b.根據指定的分隔符(不指定是位空白字元)将該行切割位列,使用$0(整行),$1,$2,$3...(第一列,第二列,...)

c.可以指定行号,列号,切割符,操作後分隔符

案例:

chkconfig --list |grep 3:啟用 |awk '{print $1}'

tail -1 /etc/passwd |awk -F ':' 'BEGIN{OFS="---"}{print $1,$6,$7}'   ##OFS指定輸出分隔符

ifconfig eth1 |awk -F '[ :]+' 'NR==2 {print $4}'

ifconfig eth1 |awk -F '[ :]+' 'NR==2 {print "eth1_ip="$4}'  ##可以加入顯示内容

awk 'BEGIN {print "line one \nline two\nline three"}'

4.進階awk的使用:

1)awk變量:

FS:列分隔符,預設位空白

RS:行分隔符,預設位換行符

OFS:輸出列分隔符

ORS :輸出行分隔符

2)awk内置變量

NR:進行中行數

FNR:單個檔案的行數

NF:列的個數

ifconfig eth1 |awk '{print NR}'

ifconfig eth1 |awk '{print NF}'

3)自定義變量:

awk 'BEGIN{test="www.linuxfan.cn";print test}'

awk -v test="linuxfan.cn" 'BEGIN{print test}'

4)printf

使用的格式:

printf format, item1,item2, ...

特征:

a.必須指定format,用于指定後面item的輸出格式

b.printf語句不會自動列印換行符:\n

c.format格式以%+一個字元,如下:

%c:顯示字元的ASCII碼

%d,%i:十進制整數

%e:科學計數法顯示數值

%f:顯示浮點數(小數)

%s:顯示字元串

%u:無符号整數

%%:顯示%

d.修飾符:N:顯示寬度,-:左對齊,+:顯示數值符号,如%-c(左對齊)

chkconfig --list |grep 3:啟用 |awk '{printf "%-10s",$1}'  ##在統一行顯示

awk -F : '{printf "%-15s %-10d %-10s\n",$1,$3,$7}' /etc/passwd

5)awk的操作符

a.算數操作符

-x

+x

x^y

x**y

x*y

x/y

x+y

x-y

x%y

b.指派操作符

=

+=

-=

*=

/=

%=

++

--

c.布爾值

awk中,任何非0值或者非空字元串都為真,反之為假

d.比較操作符:>,<,>=,<=,==,!=,~,!~(x ~ y,字元串能被表達式y比對)

d.邏輯操作符:&&,||,!

e.條件表達式:條件?if-true-exp:if-false-exp

f.調用函數:function_name (pa1, pa2)

6)awk常見的模式類型:

a.正規表達式(regexp),格式為:/regular expression/

awk -F : '/^u/{print $1}' /etc/passwd

b.表達式(expression),值位非0或位非空是滿足條件,如$1 ~ /foo/或 $1 == "root"

awk -F : '$3>=500{print $1,$3,$7}' /etc/passwd

awk -F : '$3+1<=100&&$3+1>=10{print $1,$3,$7}' /etc/passwd

awk -F : '$2=="!!"{print $1,$2}' /etc/shadow  ##檢查未初始化密碼的使用者

passwd  -d  u01

awk -F : '$2==""{print $1}' /etc/shadow  ##列印密碼為空的使用者

awk -F : '$7~"bash$"{print $1,$3,$7}' /etc/passwd  ##比對$7為bash結束行

awk -F : '$7!~"bash$"{print $1,$3,$7}' /etc/passwd

c.比對範圍(ranges),指定的比對範圍,格式為part1,part2

awk -F : '$3==3,$3==10{print $1,$3,$7}' /etc/passwd

awk -F : '$1=="root",$1=="adm"{print $1,$3,$7}' /etc/passwd

awk -F : '/^r/,/^a/{print $1,$3,$7}' /etc/passwd

d.特殊模式(BEGIN/END)

awk -F : 'BEGIN{printf "%-10s%-10s%-20s\n","UserName","ID","Shell"}{printf "%-10s%-10s%-20s\n",$1,$3,$7}' /etc/passwd  ##在awk處理之前列印頭部BEGIN{}

awk -F : 'BEGIN{printf "%-10s%-10s%-20s\n","UserName","ID","Shell"}$7~"bash$"{printf "%-10s%-10s%-20s\n",$1,$3,$7}' /etc/passwd  ##多個模式混合使用

awk -F : 'BEGIN{printf "%-10s%-10s%-20s\n","UserName","ID","Shell"}$7~"bash$"{printf "%-10s%-10s%-20s\n",$1,$3,$7}END{print "End of report"}' /etc/passwd  ##在awk執行完成後列印尾部END{}

awk -v i=1 '$5~"yum"{i++}END{print "yum use times:", i}' /var/log/messages

/正規表達式/:使用通配符的擴充集合。

關系表達式:如字元串或數字的比較。

模式比對表達式:模式(指定一個行的範圍,不包含BEGIN,END)

7)常見的action:

expressions:表達式

control satatements:控制語句

compound statements:混合語句

input statements:輸入語句

output statements:輸出語句

8)action中的控制語句:

a.if-else

文法:if (condition) command action1; else command action2

awk -F : '$7~"bash"{if ($1=="root") print $1, "admin";else print $1, "Common User"}' /etc/passwd

awk -F : -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd

awk -F : -v sum=0 '$7~"bash"{if ($1=="root") print $1, "admin" sum++;else print $1, "Common User" sum++}END{print "can login user num:",sum}' /etc/passwd  ##二合一

awk -F : '$7~"bash$"{if ($1=="root") printf "%-15s: %s\n",$1,"admin";else printf "%-15s: %s\n",$1,"common user"}' /etc/passwd  ##格式化輸出

b.while循環:循環字段,awk本身就是行的循環

文法:while (condition){statement1;statement2;...}

awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd  ##循環列印前3列

awk -F : '{i=1;while (i<NF) {if (length($i)<=4) print $i;i++}}' /etc/passwd ##循環整行,并列印出長度小于4的字段列

c.do-while

文法:do {statement1;statement2;...} while (condition)

awk -F : '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd

d.for

文法:for (variable assignment;condition;iteration process){statement1, statement2,...}

awk -F : '{for(i=1;i<=3;i++) print $i}' /etc/passwd

for循環周遊數組元素:

文法:for (i in array) {statement1, statement2,...}

awk -F : '{SH[$NF]++;}END{for (i in SH){print i,SH[i]}}' /etc/passwd

netstat -ant |awk '/^tcp/{++S[$NF]}END{for(a in S) print a, S[a]}'

awk '{counts[$1]++}END{for (url in counts) print url,"access times:",counts[url]}' /var/log/httpd/access_log

awk '{S[$5]++}END{for (i in S) print i,S[i]}' /var/log/messages

awk '{AH[$1]++}END{for (i in AH) printf "%-20s:%s\n", i, AH[i]}' /var/log/httpd/access_log

9).awk中的數組

array[index-expression]

index-expression可以使用任意字元串;需要注意的是,如果某資料組元素事先不存在,那麼在引用其時,awk會自動建立此元素并初始化為空串;是以,要判斷某資料組中是否存在某元素,需要使用index in array的方式。要周遊數組中的每一個元素,需要使用如下的特殊結構:

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

例如:

state[abc]=3

state[efg]=6

for (A in state) {print A,state[A]}  ##A一定是index-expression(下标abc/efg),state[A]是一個具體的值(3/6)

[root@localhost ~]# netstat -ant

Active Internet connections (servers and established)

Proto Recv-Q Send-Q Local Address    Foreign Address        State     

tcp        0      0 0.0.0.0:22       0.0.0.0:*           LISTEN     

tcp        0      0 127.0.0.1:25     0.0.0.0:*           LISTEN     

tcp        0      0 192.168.1.106:22 192.168.1.101:36318 ESTABLISHED

以上指令顯示的結果中,每一行最後一個字段為狀态,若要統計每種狀态的個數,隻需要将state作為數組下标,由于awk本身就是一個行的循環,是以隻需要給數字自加1(++)即可實作統計,具體操作如下:

netstat -ant |awk '{S[$6]++}END{for(i in S){print i,S[i]}}'

繼續閱讀