Chinaunix首页 | 论坛 | 博客
  • 博客访问: 121134
  • 博文数量: 27
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 280
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-15 19:04
文章分类

全部博文(27)

文章存档

2015年(1)

2014年(26)

分类: 系统运维

2014-03-06 17:55:16

以前学awk的时候没有好的习惯,不知道把一些好的例子给记录下来,等到用的时候却怎么也想不起来。
现在把这些东西都记录在博客里面。可以方便查询,也可以共享给同行们参阅。如果文章中有错误的或者有不同意见的请给我留言! 

过滤IP地址的
grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'


grep -Po '(\d+.){3}(\d+)'



 小例子

jack  huaxue   90
  tom  huaxue    70
  jack  shuxue    99
  tom  shuxue    80


要求用shell得到每个人的平均分,思路很简单,要是python的话直接dict记住总分再记住科目数,最后一除就行了。但是要求用shell,怎么办?还好awk就有关联数组的功能,因此写出如下脚本aver.awk:

awk '{if (NF == 3){if ($1 in arr){arr[$1]+=$3;cnt[$1]++}else{arr[$1]=$3;cnt[$1]=1}}}END{for (k in arr){print k "aver:"arr[k]/cnt[k]}}' a
 jackaver:94.5
 tomaver:75

 

统计访问量最大的元素
awk '{a[$10/1024" "$7" "$11]++}END{for (i in a)print a[i],i}' web.log|sort -nr -k 1|more

awk '{a[$10/1024" "$7" "$11]++}END{for (i in a)print a[i],i}' web.log|sort -nr -k 1|awk '{if ($2 > 1000) print $0}'|more

统计单个元素字节数最大的元素 (单位为 KB)
 awk '{a[$10/1024" "$7" "$11]++}END{for (i in a)print a[i],i}' web.log|sort -nr -k 2|more

统计单个元素字节数为1M以上的元素的访问量 (单位为 KB)
 cat  |awk '{a[$10/1024" "$7" "$11]++}END{for (i in a)print a[i],i}' web.log|sort -nr -k 1|awk '{if ($2 > 1000)}'more

统计总的流量,第一个是M单位 第二个是G单位
awk '{print $10/1024}' web.log |awk '{a+=$1}END{print a/1024}'
 59509.5
 awk '{print $10/1024}' web.log |awk '{a+=$1}END{print a/1024/1024}'
 58.1148

统计图片总流量
grep -E "jpg|gif" web.log|awk '{print $10/1024}' |awk '{a+=$1}END{print a/1024/1024}'

统计动态图片总流量
grep "gif"|awk '{print $10/1024}' |awk '{a+=$1}END{print a/1024/1024}'


http://blog.163.com/vindiesel@126/blog/static/65893019201321255822428/

我写的
awk '{if($2 in a);else{a[$2]=$0}}END{for(b in a)print a[b]}' urrfile

后来别人给出更简单的答案
awk ' !($2 in i){ i[$2]; print } ' urrfile

现在看来,还可以更简单些
awk '!a[$2]++' urrfile


 awk '{print $10/1024}' web.log |awk '{a+=$1}END{print a}'


 [root@kefu log_guaixun]# awk '{print $10/1024}' web.log |awk '{a+=$1}END{print a}'
 6.09377e+07
 [root@kefu log_guaixun]# awk '{print $10/1024}' web.log |awk '{a+=$1}END{print a/1024}'
 59509.5
 [root@kefu log_guaixun]# awk '{print $10/1024}' web.log |awk '{a+=$1}END{print a/1024/1024}'
 58.1148
 [root@kefu log_guaixun]# cat web.log |grep -E "jpg|gif"|awk '{print $10/1024}' |awk '{a+=$1}END{print a/1024/1024}'
 56.8914
 [root@kefu log_guaixun]# cat web.log |grep -E "gif"|awk '{print $10/1024}' |awk '{a+=$1}END{print a/1024/1024}'


 cat demo_access.log |grep "28/Apr/2012"|sed -n '/03:25/,/05:30/p'


检查302状态
awk '{if($9==302)print $7,$11}'|awk -F\" '{print $1,$2}'|awk '{a[$1]++;b=$1;c[b]=$2}END{for (i in a)print a[i],i,c[b]}'|sort -nr|more


 wtp 383: mac 00:27:1D:04:17:75  wlan 1 base vlan 15  wlan 5  wlan 7 base vlan 15  wlan 9 base vlan 15  wlan 10 base vlan 15
变成
wtp 383:
 mac 00:27:1D:04:17:75
 radio apply wlan 1 base vlan 15
 radio apply wlan 5
 radio apply wlan 7 base vlan 15
 radio apply wlan 9 base vlan 15
 radio apply wlan 10 base vlan 15

awk '{printf("%s%s\n%s%s\n",$1,$2,$3,$4);T="radio reply";split($0,a,"wlan");for(i=2;i<7;i++)print T,"wlan" a[i]}'

awk '!a[$1]++' aa
 ! a[$1] ++
  0为假, !0 为真
 以第一列(逗号分隔)为索引的数组元素的值为0则输出,输出后数组元素值++, 后面的行$1相同时a[$1]的值就不为0了。

 

 awk '/abc/,/aaa/{print $0}' aa  意思是前面匹配abc 结尾要匹配aaa
 abc 123
 abs 234
 aaa 234

  cat a
 123 343
 abc 123
 abs 234
 aaa 234
 111 121

printf  格式化处理  printf 默认不打印\n 需要自己添加
%i
 %s  字符 最常用
%u
 %e
 %g
 %f
 %c
 %d
 

控制语句  if ,while, for, case, do ... while, break, continue, next

if
 [root@localhost ~]# awk -F: '{if ($3==0){printf "%-15s %s\n",$1,"administrator"}else{printf "%-15s %s\n",$1,"common-user"}}' /etc/passwd
 root            administrator
 bin             common-user
 daemon          common-user

 

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

cat /var/log/secure |awk  'BEGIN{a=0}/Fail/{a++}END{print a}'
 1111


 while
  awk -F: '{i=1;while (i<=3) {printf "%s ",$i;i++};printf "\n"}' /etc/passwd
 root x 0
 bin x 1
 daemon x 2


 while 遍历每一个块的字符  进行条件匹配
[root@localhost ~]# cat a
 89 3242 23 459
 123 43 54654 2
 123 345 34 67 567 67863
 [root@localhost ~]# awk '{i=1; while (i<=NF){if ($i>=100)print $i; i++}}' a
 3242
 459
 123
 54654
 123
 345
 567
 67863

每一个字符长度等于3的答应出来
[root@localhost ~]#awk '{i=1; while (i<=NF){if (length($i) == 3)print $i; i++}}' a
 459
 123
 123
 345
 567


 do-while 至少执行一次循环体,不管满足条件与否
 语法: do{statement1,statement2.....} while {condition}
 awk -F: '{i=1;do{print $i;i++}while(i<=3)}' /etc/passwd
 awk -F: '{i=4;do{print $i;i--}while(i<=4)}' /etc/passwd

 

for 循环
[root@localhost ~]# cat a
 89 3242 23 459
 123 43 54654 2
 123 345 34 67 567 67863
 [root@localhost ~]# awk '{for (i=1;i<=NF;i++){if ($i>=100)print $i}}' a
 3242
 459
 123
 54654
 123
 345
 567
 67863

for (i=1;i<=NF;i++)  逐行读取 NF

bash
    array=(“mon” "tue" "wed")

关联数组
   array=(a='mon' b='tue' c='wed')
    array[c]

[root@localhost ~]# awk -F: '$NF!~/^$/{a[$NF]++}END{for (b in a){printf "%15s:%i\n",b,a[b]}}' /etc/passwd
       /bin/sync:1
       /bin/bash:1
   /sbin/nologin:29
      /sbin/halt:1
  /sbin/shutdown:1

NF:
 /bin/bash
 /sbin/nologin

a[/bin/bash]
 a[/sbin/nologin]

a[/bin/bash]=1
 a[/sbin/nologin]=1
 a[/sbin/nologin]=2

 

[root@localhost ~]# netstat -an|awk '/^tcp/{a[$NF]++}END{for (i in a)print i,a[i]}'
 LISTEN 8
 ESTABLISHED 2


 next
提前结束对文本行文本处理,并接着处理下一行:例如下面的命令显示其ID号为奇数的用户

[root@localhost ~]# awk -F: '{if($3%2==0)next;print $1,$3}' /etc/passwd
 bin 1
 adm 3
 sync 5
 halt 7
 news 9


 awk '{a+=$1}END{print a}' b
 awk的加法


awk的内置函数
length([string])
 功能:取字符串长度


substr(string,start[, length])
功能:取string字符串中的字串,从start开始取,取length个;start从1开始计数

echo "123456789" | awk '{print substr($0, 5, 2)}'
 56


 split(string,array[,fieldsep [,seps ])
功能:将string表示的字符串以fieldsep为分隔符进行分割,并将分割后的结果保持至array为名的数组中:数组下表从0开始的序列:

netstat -an|awk '/:80\>/{split($5,clients,":");IP[clients[1]]++}END{for (i in IP)print IP[i],i}'

统计出访问80端口的 ip 访问次数

 

[root@baidu ~]# df -h
文件系统              容量  已用 可用 已用% 挂载点
/dev/sdb3             125G   99G   20G  84% /
 /dev/sda1              99M   13M   82M  14% /boot
 tmpfs                 3.9G     0  3.9G   0% /dev/shm
 /dev/mapper/VolGroup00-LogVol00
                       262G  242G  6.1G  98% /53kf
 [root@baidu ~]# df -h |awk '!/^文件/{split($5,a,"%");if(a[1] > 10){print $1,$5}}'
 /dev/sdb3 84%
 /dev/sda1 14%

echo 123456 |awk -F '' '{for (i=1;i<=NF;i++)printf " "$i}'
  1 2 3 4 5 6


 
 awk '!/\/\*/,/\*\//' d
复制代码
 取反仅仅针对/\/\*/,打印的是不匹配/\/\*/开始到匹配/\*\//结束的行,
 和你想要表达的不在/* */之间的行含义不同。
 这样写能实现你想要的
awk '/\/\*/,/\*\//{k=1} !k{print} {k=0}' test.txt
 aaaaa
 bbbbb
 cccc
复制代码

 

[root@centos shell]# find ./ -name "init*"  -ok rmdir {} \;
 < rmdir ... ./init2 > ?

 


 

阅读(1496) | 评论(0) | 转发(0) |
0

上一篇:awk学习笔记

下一篇:English study for unit 1-3

给主人留下些什么吧!~~