您的位置:首页 > 其它

awk进阶

2016-07-15 18:05 357 查看
awk:报告生成工具,能够将文本处理为比较直观理想的报表。主要是对文本结果的格式化,也能处理文本搜索,但是效率要比grep低的多的多。

用法格式:

awk [options] 'script' file1,file2 . . .
'PATTERN{ action }'
一、分隔符:字段分隔符,行分隔符

-F: 输入分隔符,下面以:号为分隔符。
[root@node1 ~]#  awk -F: '{print $1,$7}' /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
uucp /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
gopher /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
BEGIN模式:正式awk处理文本之前做一些准备工作。#必须在awk处理之前
[root@node1 ~]# awk -F: 'BEGIN {print "Username Shell"} {print $1,$7}' /etc/passwd
Username Shell
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
uucp /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
gopher /sbin/nologin
[root@node1 ~]# awk  'BEGIN {FS=":"} {print $1,$7}' /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
uucp /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
gopher /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
OFS:输出格式,OFS=***** 输出格式如下:
[root@node1 ~]# awk  'BEGIN {FS=":"; OFS="*****"} {print $1,$7}' /etc/passwd
root*****/bin/bash
bin*****/sbin/nologin
daemon*****/sbin/nologin
adm*****/sbin/nologin
lp*****/sbin/nologin
sync*****/bin/sync
shutdown*****/sbin/shutdown
halt*****/sbin/halt
mail*****/sbin/nologin
uucp*****/sbin/nologin
operator*****/sbin/nologin
games*****/sbin/nologin
gopher*****/sbin/nologin
ftp*****/sbin/nologin
nobody*****/sbin/nologin
END模式:
[root@node1 ~]# awk  'BEGIN {FS=":"; OFS=":"} {print $1,$7}  END{print "=========END=========="}' /etc/passwd
root:/bin/bash
bin:/sbin/nologin
daemon:/sbin/nologin
adm:/sbin/nologin
lp:/sbin/nologin
sync:/bin/sync
shutdown:/sbin/shutdown
halt:/sbin/halt
mail:/sbin/nologin
uucp:/sbin/nologin
operator:/sbin/nologin
games:/sbin/nologin
gopher:/sbin/nologin
ftp:/sbin/nologin
nobody:/sbin/nologin
vcsa:/sbin/nologin
saslauth:/sbin/nologin
postfix:/sbin/nologin
sshd:/sbin/nologin
nginx:/sbin/nologin
apache:/sbin/nologin
=========END==========
完善一下
[root@node1 ~]# awk  'BEGIN {FS=":"; OFS=":"; print "Username  Shell"} {print $1,$7}  END{print "=========END=========="}' /etc/passwd
Username  Shell
root:/bin/bash
bin:/sbin/nologin
daemon:/sbin/nologin
adm:/sbin/nologin
lp:/sbin/nologin
sync:/bin/sync
shutdown:/sbin/shutdown
halt:/sbin/halt
mail:/sbin/nologin
uucp:/sbin/nologin
operator:/sbin/nologin
games:/sbin/nologin
gopher:/sbin/nologin
ftp:/sbin/nologin
nobody:/sbin/nologin
vcsa:/sbin/nologin
saslauth:/sbin/nologin
postfix:/sbin/nologin
sshd:/sbin/nologin
nginx:/sbin/nologin
apache:/sbin/nologin
=========END==========
NF显示字段:
[root@node1 ~]# df -lh |awk '{print NF}'
7
1
5
6
6


二、正则表达式:/PATERN/只匹配符合条件的行。
例:显示以sh结尾的行
[root@node1 ~]# awk  'BEGIN {FS=":"; OFS=":"; print "Username  Shell"} /sh$/ {print $1,$7}  END{print "=========END=========="}' /etc/passwd
Username  Shell
root:/bin/bash
=========END==========
表达式:>, <,>-,<=,~,!~
匹配ID号大于50的账号
[root@node1 ~]# awk -F: '$3>=50 {print $1,$3}' /etc/passwd
nobody 99
vcsa 69
saslauth 499
postfix 89
sshd 74
nginx 498
匹配/bin/bash账号
[root@node1 ~]# awk -F: '$7~/bash/ {print $1,$3}' /etc/passwd
root 0
test1 500
test2 501
不匹配/bin/bash账号
[root@node1 ~]# awk -F: '$7!~/bash/ {print $1,$3}' /etc/passwd
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
uucp 10
operator 11
games 12
gopher 13
ftp 14
nobody 99
vcsa 69
saslauth 499
postfix 89
sshd 74
nginx 498
apache 48
三、printf

printf命令的使用格式:
printf fromat,item1,item2...
要点:
1、其与print命令的最大不同是,printf所需要指定format;
2、format用于指定后面的每个item的输出格式;
3、printf语句不会自动打印换行符;\n
format格式的指示符都以%开头,后跟一个字符;如下:
%c;显示字符的ASCII码;
%d,%i;十进制整数;
%e,%E;科学计数法数值;
%f;显示浮点数;
%g,%G;以科学计数法的格式或浮点格式显示数值;
%s;显示字符串;
%u:无符号整数;
%%;显示%自身;

修饰符:
N:显示宽度;
-:左对齐;
+:显示数值符号;
例子
[root@node1 ~]# awk -F: '{printf "%15s %i\n",$1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
uucp 10
operator 11
games 12
gopher 13
ftp 14
nobody 99
vcsa 69
saslauth 499
postfix 89
sshd 74
nginx 498
apache 48
test1 500
test2 501
%u显示无符号整数,-%15s左对齐
[root@node1 ~]# awk -F: '{printf "%-15s %u\n",$1,$3}' /etc/passwd
root            0
bin             1
daemon          2
adm             3
lp              4
sync            5
shutdown        6
halt            7
mail            8
uucp            10
operator        11
games           12
gopher          13
ftp             14
nobody          99
vcsa            69
saslauth        499
postfix         89
sshd            74
nginx           498
apache          48
test1           500
test2           501
五、算术操作符:

-x:负值
+x:转换为数值:
x^y;
x**y 次方
x*y 乘法
x/y
x+y
x-y;
x%y

赋值操作符:
=
+=
-=
*=
/=
%=
^=
**=
++
--
需要注意的是,如果其模式为=号,此时使用/*/可能会有语法错误,应以/[=]/替代;

布尔值
awk 中任何非0值或非空字符串为真,反之就为假:

比较操作符
x<y True if x is less than y.
x<=y True if x less than or equal to y.
x>y True if x is greater than y.
x>=y True if x is greater than or equal to y.
x==y True if x is equal to y.
x!=y True if x is not equal to y .
x~y True if the string x matches the regexp denoted by y.
x!~y True if the string x does not match the regexp dented by y.

表达式建的逻辑关系符:
&&
||

例:显示ID号大于500并且是/bin/bash的账号。
[root@node1 ~]# awk -F:  '$3>=500 &&$7~/bash/ {printf "%-15s %i %s\n ",$1,$3,$7}' /etc/passwd
test1           500 /bin/bash
test2           501 /bin/bash


条件表达式:
selector?if-true-exp:if-false-exp

if selector;then
if-true-exp
else
if-false-exp
fi

函数调用:
function_name(para1,para2)

六、常用的模式类型:
1、Regexp:正则表达式,格式为/regular expression/
2、expression:表达式,其值非0或为空字符时满足条件,如:$1 ~/foo/ 或$1=="abc",用运算符~(匹配)和!~(不匹配)。
3、Ranges:指定的匹配范围,格式为Pat1,Pat2
4、BEGIN/END:特殊模式,仅在awk命令执行前一次或结束前运行一次。
5、Empty(空模式):匹配任意输入行;
常见的Action
1、Expression;
2、Control statements
3、Compound statements
4、Input statements
5、Output statements
/正则表达式/:使用通配符的扩展集
关系表达式:可以用下面运算符进行操作,可以是字符或数字比较,如$2>$1选择第二个字段比第一个字段长的行。
模式匹配表达式:
模式:指定一个行的范围,改语法不能包括BEGIN和END模式。
例:打印abc开始到aaa结束所匹配的行内容
[root@node1 ~]# cat test1.sh
mmm
opq
abc 1
cde 2
aaa 3
mnt 4
abc 5
hello 6
are 7
aaa 8
haow 9
are 10
you 11
abc 12
hello 13
world 14
[root@node1 ~]# awk '/abc/,/aaa/ {print $0}' test1.sh
abc 1
cde 2
aaa 3
abc 5
hello 6
are 7
aaa 8
abc 12
hello 13
world 14
七、控制语句:

if-else
语法:if(condition){then-body} else {[ else-body ]}
例子:如果用户的ID号是0,就是管理员。否则就是普通用户
[root@node1 ~]# awk -F: '{if ($1=="root") print $1, "Admin";else print $1,"Common User"}' /etc/passwd
root Admin
bin Common User
daemon Common User
adm Common User
lp Common User
sync Common User
shutdown Common User
halt Common User
mail Common User
uucp Common User
operator Common User
games Common User
gopher Common User
ftp Common User
nobody Common User
vcsa Common User
saslauth Common User
postfix Common User
sshd Common User
nginx Common User
apache Common User
test1 Common User
test2 Common User
显示ID号大于500的用户总数
[root@node1 ~]# awk -F: -v sum=0 '{if ($3>=500) sum++} END{print sum}' /etc/passwd
2
while

语法:while (condition) {statement1;statment2;...}
主要目的是每一个片中进行循环,不是每一行哦。

[root@node1 ~]# awk -F: '{i=1;while (i<3) {print $i;i++}}' /etc/passwd
root
x
bin
x
daemon
x
adm
x
lp
x
sync
x
shutdown
x
halt
x
mail
x
uucp
x
operator
x
games
x
gopher
x
ftp
x
nobody
x
vcsa
x
saslauth
x
postfix
x
sshd
x
nginx
x
apache
x
test1
x
test2
x
[root@node1 ~]# awk -F: '{i=1;while (i<=NF) {if (length($i)>=4) {print $i};i++}}' /etc/passwd
root
root
/root
/bin/bash
/bin
/sbin/nologin
daemon
daemon
/sbin
/sbin/nologin
/var/adm
/sbin/nologin
/var/spool/lpd
/sbin/nologin
sync
sync
/sbin
/bin/sync
shutdown
shutdown
/sbin
/sbin/shutdown
halt
halt
/sbin
/sbin/halt
mail
mail
/var/spool/mail
/sbin/nologin
uucp
uucp
/var/spool/uucp
/sbin/nologin
operator
operator
/root
/sbin/nologin
games
games
/usr/games
/sbin/nologin
gopher
gopher
/var/gopher
/sbin/nologin
FTP User
/var/ftp
/sbin/nologin
nobody
Nobody
/sbin/nologin
vcsa
virtual console memory owner
/dev
/sbin/nologin
saslauth
"Saslauthd user"
/var/empty/saslauth
/sbin/nologin
postfix
/var/spool/postfix
/sbin/nologin
sshd
Privilege-separated SSH
/var/empty/sshd
/sbin/nologin
nginx
Nginx web server
/var/lib/nginx
/sbin/nologin
apache
Apache
/var/www
/sbin/nologin
test1
/home/test1
/bin/bash
test2
/home/test2
/bin/bash
[root@node1 ~]# awk -F: '{i=1;while (i<=3) {printf "%s", $i;i++;};printf "\n"}' /etc/passwd
rootx0
binx1
daemonx2
admx3
lpx4
syncx5
shutdownx6
haltx7
mailx8
uucpx10
operatorx11
gamesx12
gopherx13
ftpx14
nobodyx99
vcsax69
saslauthx499
postfixx89
sshdx74
nginxx498
apachex48
test1x500
test2x501
打印大于100的数值,每行显示
[root@node1 ~]# cat test2.sh
89 746 38 8489 99
55 34
857 7384 75492
88
56
13 83
[root@node1 ~]# awk '{i=1;while (i<=NF) {if ($i>=100) print $i;i++}}' test2.sh
746
8489
857
7384
75492
do-while

语法:do{statemenet1,statement2,...} while(condition)
先执行一次,不管条件满足与否至少执行一次循环体。
[root@node1 ~]# awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd
for
语法:for (variable assignment;condition;iteration process) {statement1,statement2,...}
[root@node1 ~]# awk -F: '{for(i=1;i<3;i++) print $i}' /etc/passwd
root
x
bin
x
daemon
x
adm
x
lp
x
sync
x
shutdown
[root@node1 ~]# awk -F: '{for(i=1;i<NF;i++) {if (length($i)>=4) {print $i}}}' /etc/passwd
root
root
/root
/bin
daemon
daemon
/sbin
/var/adm
/var/spool/lpd
sync
sync
/sbin
shutdown
shutdown
/sbin
halt
halt
/sbin
mail
mail
/var/spool/mail
uucp
uucp
/var/spool/uucp
operator
operator
/root
games
games
/usr/games
gopher
gopher
/var/gopher
八、awk数组:
数组:一组连续的可存多个值内存空间。关联数组
例子:统计每个shell类型的次数。
$NF!~最后一个字段不为空/^$/ (A IN BASH) 遍历每一组数组的下标。
如A=[sbin/shutdown] 第二次A=[/bin/bash]...
BASH[A] 显示数组的次数。
[root@node1 ~]# awk -F: '$NF!~/^$/{BASH[$NF]++}END{for (A in BASH){printf "%15s:%i\n",A,BASH[A]}}' /etc/passwd
/sbin/shutdown:1
/bin/bash:3
/sbin/nologin:17
/sbin/halt:1
/bin/sync:1
例:netstat统计State为TCP的状态

[root@node1 ~]# netstat -tanl |awk '/^tcp/ {state[$NF]++}END{for (S in state) print S,state[S]}'
ESTABLISHED 1
LISTEN 4
例:统计httpd日志中访问的IP次数
[root@rmt logs]# awk '{ip[$1]++} END {for (A in ip) print A,ip[A]}' access_log
192.168.254.50 1
192.168.254.60 91
192.168.254.220 9
192.168.254.56 9
192.168.254.66 43
192.168.254.57 96
192.168.254.58 7
九、awk的内置函数
split(string,array [,fieldsep[,seps] ])
功能:将string表示的字符串以fieldsep为分隔,并将分割后的结果保存至array为名的数组中:数组下标为从1开始的序列:

length([string])
功能:返回string字符串字符的个数

substr(string,start[,length])
功能:取string字符串中的子串,从start开始,取length个;start从1开始计数:
[root@rmt logs]# netstat -ant |awk '/:80\>/{split($5,clients,":");IP[clients[4]]++}END{for (i in IP){print IP[i],i}}'|sort -rn |head -50
3
例:查找分区大于%20的文件系统
[root@rmt-app1 logs]# df -lh
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       20G  2.2G   17G  12% /
tmpfs            16G     0   16G   0% /dev/shm
/dev/xvdb1      493G  333G  135G  72% /usr/local
[root@rmt-app1 logs]# df -lh |awk '!/^File/{split ($5,percent,"%"); if(percent[1]>=20){print $1}}'
/dev/xvdb1
Linux Web服务器网站故障分析常用的命令
系统连接状态篇:
1.查看TCP连接状态
netstat -nat |awk ‘{print $6}’|sort|uniq -c|sort -rn
netstat -n | awk ‘/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}’ 或
netstat -n | awk ‘/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}’
netstat -n | awk ‘/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"t",arr[k]}’
netstat -n |awk ‘/^tcp/ {print $NF}’|sort|uniq -c|sort -rn
netstat -ant | awk ‘{print $NF}’ | grep -v ‘[a-z]‘ | sort | uniq -c

2.查找请求数请20个IP(常用于查找攻来源):
netstat -anlp|grep 80|grep tcp|awk ‘{print $5}’|awk -F: ‘{print $1}’|sort|uniq -c|sort -nr|head -n20
netstat -ant |awk ‘/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A[i],i}’ |sort -rn|head -n20
3.用tcpdump嗅探80端口的访问看看谁最高
tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." ‘{print $1"."$2"."$3"."$4}’ | sort | uniq -c | sort -nr |head -20
4.查找较多time_wait连接
netstat -n|grep TIME_WAIT|awk ‘{print $5}’|sort|uniq -c|sort -rn|head -n20
5.找查较多的SYN连接
netstat -an | grep SYN | awk ‘{print $5}’ | awk -F: ‘{print $1}’ | sort | uniq -c | sort -nr | more
6.根据端口列进程
netstat -ntlp | grep 80 | awk ‘{print $7}’ | cut -d/ -f1

网站日志分析篇1(Apache):
1.获得访问前10位的ip地址
cat access.log|awk ‘{print $1}’|sort|uniq -c|sort -nr|head -10
cat access.log|awk ‘{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}’
2.访问次数最多的文件或页面,取前20
cat access.log|awk ‘{print $11}’|sort|uniq -c|sort -nr|head -20
3.列出传输最大的几个exe文件(分析下载站的时候常用)
cat access.log |awk ‘($7~/.exe/){print $10 " " $1 " " $4 " " $7}’|sort -nr|head -20
4.列出输出大于200000byte(约200kb)的exe文件以及对应文件发生次数
cat access.log |awk ‘($10 > 200000 && $7~/.exe/){print $7}’|sort -n|uniq -c|sort -nr|head -100
5.如果日志最后一列记录的是页面文件传输时间,则有列出到客户端最耗时的页面
cat access.log |awk ‘($7~/.php/){print $NF " " $1 " " $4 " " $7}’|sort -nr|head -100
6.列出最最耗时的页面(超过60秒的)的以及对应页面发生次数
cat access.log |awk ‘($NF > 60 && $7~/.php/){print $7}’|sort -n|uniq -c|sort -nr|head -100
7.列出传输时间超过 30 秒的文件
cat access.log |awk ‘($NF > 30){print $7}’|sort -n|uniq -c|sort -nr|head -20
8.统计网站流量(G)
cat access.log |awk ‘{sum+=$10} END {print sum/1024/1024/1024}’
9.统计404的连接
awk ‘($9 ~/404/)’ access.log | awk ‘{print $9,$7}’ | sort
10. 统计http status
cat access.log |awk ‘{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}'
cat access.log |awk '{print $9}'|sort|uniq -c|sort -rn
10.蜘蛛分析,查看是哪些蜘蛛在抓取内容。
/usr/sbin/tcpdump -i eth0 -l -s 0 -w - dst port 80 | strings | grep -i user-agent | grep -i -E 'bot|crawler|slurp|spider'
网站日分析2(Squid篇)按域统计流量
zcat squid_access.log.tar.gz| awk '{print $10,$7}' |awk 'BEGIN{FS="[ /]"}{trfc[$4]+=$1}END{for(domain in trfc){printf "%st%dn",domain,trfc[domain]}}'
数据库篇
1.查看数据库执行的sql
/usr/sbin/tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | egrep -i 'SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL'
系统Debug分析篇

1.调试命令
strace -p pid
2.跟踪指定进程的PID
gdb -p pid
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  awk