AWK常用技巧
1.1 介绍
awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。
它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。
awk 是一种很棒的语言,它适合文本处理和报表生成,其语法较为常见,借鉴了某些语言的一些精华,如 C 语言等。在 linux 系统日常处理工作中,发挥很重要的作用,掌握了 awk将会使你的工作变的高大上。
1.1.1 AWK原理
这需要一个例子来说明,你将会见到/etc/passwd 文件的内容出现在眼前。
awk '{print $0}' /etc/passwd
echo clsn|awk '{print "hello,world"}'
awk '{ print "clsn" }' /etc/passwd
现在,解释 awk 做了些什么。调用 awk时,我们指定/etc/passwd 作为输入文件。执行 awk 时,它依次对/etc/passwd 中的每一行执行 print 命令。所有输出都发送到 stdout,所得到的结果与执行 cat /etc/passwd 完全相同。现在,解释{ print }代码块。在 awk 中,花括号用于将几块代码组合到一起,这一点类
似于C 语言。在代码块中只有一条 print 命令。在awk 中,如果只出现 print 命令,那么将打印当前行的全部内容。
再次说明,awk 对输入文件中的每一行都执行这个脚本。
1.2 AWK常用速查表
1.2.1 AWK运算符
运算符 |
说明 |
赋值运算符 |
|
= += -= *= /= %= ^= **= |
赋值语句 |
逻辑运算符 |
|
|| |
逻辑或 |
&& |
逻辑与 |
正则运算符 |
|
~ !~ |
匹配正则表达式和不匹配正则表达式 |
关系运算符 |
|
< <= > >= != == |
关系运算符 |
算术运算符 |
|
+ - |
加,减 |
* / & |
乘,除与求余 |
+ - ! |
一元加,减和逻辑非 |
^ *** |
求幂 |
++ -- |
增加或减少,作为前缀或后缀 |
其他运算符 |
|
$ |
字段引用 |
空格 |
字符串链接符 |
?: |
三目运算符 |
In |
数组中是否存在某键值 |
1.2.2 常用AWK内置变量
变量名 |
属性 |
$0 |
当前记录 |
$1~$n |
当前记录的第 n 个字段 |
FS |
输入字段分隔符 默认是空格 |
RS |
输入记录分割符 默认为换行符 |
NF |
当前记录中的字段个数,就是有多少列 |
NR |
已经读出的记录数,就是行号,从 1 开始 |
OFS |
输出字段分隔符 默认也是空格 |
ORS |
输出的记录分隔符 默认为换行符 |
1.2.3 awk中的正则
元字符 |
功能 |
示例 |
解释 |
^ |
行首定位符 |
/^root/ |
匹配所有以 root 开头的行 |
$ |
行尾定位符 |
/root$/ |
匹配所有以 root 结尾的行 |
. |
匹配任意单个字符 |
/r..t/ |
匹配字母 r,然后两个任意字符,再以 l 结尾的行,比如 root,r33l 等 |
* |
匹配 0 个或多个前导字符(包括回车) |
/a*ool/ |
匹配 0 个或多个 a 之后紧跟着 ool 的行,比如 ool,aaaaool 等 |
+ |
匹配 1 个或多个前导字符 |
/a+b/ |
匹配 1 个或多个 a 加 b 的行,比如 ab,aab 等 |
? |
匹配 0 个或 1 个前导字符 |
/a?b/ |
匹配 b 或 ab 的行 |
[] |
匹配指定字符组内的任意一个字符 |
/^[abc] |
匹配以字母 a 或b 或 c 开头的行 |
[^] |
匹配不在指定字符组内任意一个字符 |
/^[^abc]/ |
匹配不以字母 a 或 b 或 c 开头的行 |
() |
子表达式组合 |
/(rool)+/ |
表示一个或多个 rool 组合,当有一些字符需要组合时,使用括号括起来 |
| |
或者的意思 |
/(root)|B/ |
匹配root 或者 B 的行 |
\ |
转义字符 |
/a\/\// |
匹配 a// |
~,!~ |
匹配,不匹配的条件语句 |
$1~/root/ |
匹配第一个字段包含字符root 的所有记录 |
x{m} |
x 重复m 次 |
/(root){3}/ |
需要注意一点的是,root 加括号和不 |
x{m,} |
x 重复至少m 次 |
/(root){3,}/ |
加括号的区别,x 可以表示字符串也 |
X{m,n} |
x 重复至少 m 次, 但不超过 n 次 |
/(root){5,6}/ |
可以只是一个字符,所以/root\{5\}/ 表示匹配roo 再加上5 个t,及roottttt |
|
需要指定参数: -posix 或者 --re-interval 没 有该参数不能使用该模式 |
cat rex.txt smierth,harry smierth,reru robin,tom |
/\(root\)\{2,\}/ 则 表 示 匹 配 rootrootrootroot 等 awk -posix '/er\{1,2\}/' rex.text smierth,harry smierth,reru |
1.2.4 awk 常用函数表
函数 |
说明 |
gsub( Ere, Repl, [ In ] ) |
除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行,。 |
sub( Ere, Repl, [ In ] ) |
用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。 |
index( String1, String2 ) |
在由 String1 参数指定的字符串(其中有出现 String2 指定的参数)中,返回位置,从 1 开始编号。如果 String2 参数不在 String1 参数中出现,则返回 0(零)。 |
length [(String)] |
返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。 |
blength [(String)] |
返回 String 参数指定的字符串的长度(以字节为单位)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。 |
substr( String, M, [ N ] ) |
返回具有 N 参数指定的字符数量子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。M 参数指定为将 String 参数中的第一个字符作为编号 1。如果未指定 N 参数,则子串的长度将是 M 参数指定的位置到 String 参数的末尾 的长度。 |
match( String, Ere ) |
在 String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。 |
split( String, A, [Ere] ) |
将 String 参数指定的参数分割为数组元素 A[1], A[2], . . ., A[n],并返回 n 变量的值。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere参数)。除非上下文指明特定的元素还应具有一个数字值,否则 A 数 |
1.3 AWK实践
1.3.1 函数的简单使用
[root@clsn6 ~]# awk '{gsub(/[0-9]+/,"");print}' /tmp/passwd
root:x:::root:/root:/bin/bash
bin:x:::bin:/bin:/sbin/nologin
daemon:x:::daemon:/sbin:/sbin/nologin
adm:x:::adm:/var/adm:/sbin/nologin
lp:x:::lp:/var/spool/lpd:/sbin/nologin
sync:x:::sync:/sbin:/bin/sync
···
1.3.2 统计系统中的secure文件中谁在破解你的密码
1、找到谁在破解密码
[root@clsn6 awk]# awk '/Failed/{print $(NF-3)}' secure-20161219 |sort |uniq -c |sort -nk1
1 103.237.144.68
1 122.228.238.66
1 195.20.3.210
1 85.93.5.71
···
2、过滤出包含Failed password的行 并统计每个ip地址出现的次数
[root@clsn6 awk]# awk '/Failed/{fa[$(NF-3)]++}END{for(pol in fa)print pol,fa[pol]}' secure-20161219 |sort -rnk2
218.65.30.25 68652
218.65.30.53 34326
218.87.109.154 21201
112.85.42.103 18065
112.85.42.99 17164
218.87.109.151 17163
1.3.3 统计secure文件中每个用户,被同一ip破解多少次
1、进破解使用的用户及地址定向到文件中
[root@clsn6 awk]# awk '/Failed/{print $(NF-5),$(NF-3)}' secure-20161219 >user-ip.log
2、对文件进行去重排序测
[root@clsn6 awk]# awk '{h[$1" "$2]++}END{for(p in h) print p,h[p]}' user-ip.log |head
export 209.126.122.70 3
cvsadmin 209.126.122.70 3
user1 209.126.122.70 1
dasusr1 209.126.122.70 4
1 118.100.251.170 1
git 209.126.122.70 5
boss 195.154.50.61 1
user1 46.139.219.84 2
www 123.31.34.165 2
webmaster 195.154.50.61 1
3、操作日志文件,取出数据
[root@clsn6 awk]# awk '/Failed/{h[$(NF-5)" "$(NF-3)]++}END{for(p in h) print p,h[p]}' secure-20161219 |head
export 209.126.122.70 3
cvsadmin 209.126.122.70 3
user1 209.126.122.70 1
dasusr1 209.126.122.70 4
1 118.100.251.170 1
1.3.4 统计nginx access.log文件中对ip地址去重并统计重复数
[root@clsn6 awk]# awk '{h[$1]++}END{for(i in h) print i,h[i]}' access.log |sort -nrk2 |head
58.220.223.62 12049
112.64.171.98 10856
114.83.184.139 1982
1.3.5 统计access.log文件中每个ip地址使用了多少流量
1、流量总计
[root@clsn6 awk]# awk '{sum=sum+$10}END{print sum}' access.log
2478496663
[root@clsn6 awk]# awk '{sum=sum+$10}END{print sum/1024^3}' access.log
2.30828
2、每个ip使用的流量
[root@clsn6 awk]# awk '{h[$1]=h[$1]+$10}END{for(p in h) print p,h[p]/1024^2 }' access.log |sort -rnk2|column -t |head
114.83.184.139 29.91
117.136.66.10 21.3922
116.216.30.47 20.4716
223.104.5.197 20.4705
116.216.0.60 18.2584
1.3.6 统计access.log文件中每个ip地址使用了多少流量和每个ip地址的出现次数
[root@clsn6 awk]# awk '{count[$1]++;sum[$1]=sum[$1]+$10}END{for(pol in sum)print pol,count[pol],sum[pol]}' access.log |sort -nrk2 |column -t |head
58.220.223.62 12049 12603075
112.64.171.98 10856 15255013
114.83.184.139 1982 31362956
117.136.66.10 1662 22431302
115.29.245.13 1318 1161468
223.104.5.197 961 21464856
116.216.0.60 957 19145329
格式化命令
awk '{
count[$1]++
sum[$1]+=$10
}END{
for(pol in sum)
print pol,count[pol],sum[pol]
}' access.log |sort -nrk3 |head
格式化后执行
[root@clsn6 awk]# awk '{
count[$1]++
sum[$1]+=$10
}END{
for(pol in sum)
print pol,count[pol],sum[pol]
}' access.log |column -t| sort -nrk3 |head
114.83.184.139 1982 31362956
117.136.66.10 1662 22431302
116.216.30.47 506 21466000
223.104.5.197 961 21464856
116.216.0.60 957 19145329
114.141.164.180 695 17219553
114.111.166.22 753 17121524
223.104.5.202 871 16911512
116.228.21.187 596 15969887
112.64.171.98 10856 15255013
1.3.7 按要求得到最后面的格式的结果
文件内容
cat >next2.txg<< EOF
web01[192.168.2.100]
httpd ok
tomcat ok
sendmail ok
web02[192.168.2.101]
httpd ok
postfix ok
web03[192.168.2.102]
mysqld ok
httpd ok
EOF
想要的结果:
web01[192.168.2.100] httpd ok
web01[192.168.2.100] tomcat ok
web01[192.168.2.100] sendmail ok
web02[192.168.2.101] httpd ok
web02[192.168.2.101] postfix ok
web03[192.168.2.102] mysqld ok
web03[192.168.2.102] httpd ok
方法一:
[root@clsn6 awk]# awk '/^web/{tmp=$0} !/^web/{print tmp,$0}' next.txt
web01[192.168.2.100] httpd ok
web01[192.168.2.100] tomcat ok
web01[192.168.2.100] sendmail ok
web02[192.168.2.101] httpd ok
web02[192.168.2.101] postfix ok
web03[192.168.2.102] mysqld ok
web03[192.168.2.102] httpd ok
方法二:
[root@clsn6 awk]# awk '/^web/{tmp=$0;next}{print tmp,$0}' next.txt
web01[192.168.2.100] httpd ok
web01[192.168.2.100] tomcat ok
web01[192.168.2.100] sendmail ok
web02[192.168.2.101] httpd ok
web02[192.168.2.101] postfix ok
web03[192.168.2.102] mysqld ok
web03[192.168.2.102] httpd ok
next:停止处理当前行,从头开始处理下一行
[root@clsn6 awk]# seq 5 |awk 'NR==3{next}{print NR,$0}'
1 1
2 2
4 4
5 5
[root@clsn6 awk]# seq 5 |awk 'NR==1{next}{print NR,$0}'
2 2
3 3
4 4
5 5
跳过偶数行
[root@clsn6 awk]# seq 5 |awk 'NR%2==0{next}{print NR,$0}'
1 1
3 3
5 5
跳过奇数行
[root@clsn6 awk]# seq 5 |awk 'NR%2==1{next}{print NR,$0}'
2 2
4 4
1.3.8 统计每个学生的总成绩和平均成绩
成绩文件
cat > chengji.txt <<EOF
cc 90 98 98 96 96 92
ll 70 77 85 83 70 89
ss 85 92 78 94 88 91
nn 89 90 85 94 90 95
bb 84 88 80 92 84 82
gg 64 80 60 60 61 62
EOF
算出总和
[root@clsn6 awk]# awk '{sum=0;for(i=2;i<=NF;i++)sum+=$i;print $1,sum}' chengji.txt
cc 570
ll 474
ss 528
nn 543
bb 510
gg 387
算出平均数
[root@clsn6 awk]# awk '{sum=0;for(i=2;i<=NF;i++)sum+=$i;avg=sum/(NF-1);print $1,sum,avg}' chengji.txt
cc 570 95
ll 474 79
ss 528 88
nn 543 90.5
bb 510 85
gg 387 64.5
格式化命令
awk '{
sum=0
for(i=2;i<=NF;i++)
sum+=$i
avg=sum/(NF-1)
print $1,sum,avg
}' chengji.txt
1.3.9 打印下面语句中字符数小于6的单词
文件内容
echo "I am clsn ops,I very like linux hahahaha." > text.txt
shell方法
[root@clsn6 awk]# for i in `sed 's#,# #g' text.txt`
> do
> [ ${#i} -lt 6 ] && echo $i
> done
I
am
clsn
ops
I
very
like
linux
grep 方法
[root@clsn6 awk]# egrep -wo '[a-Z]{,6}' text.txt
I
am
clsn
ops
I
very
like
linux
awk方法
[root@clsn6 awk]# echo clsn |awk '{print length($1)}'
4
[root@clsn6 awk]# awk -F "[, ]" '{for(i=1;i<=NF;i++) if (length($i)<6) print $i}' text.txt
I
am
clsn
ops
I
very
like
linux
1.4 附录
1.4.1 sort命令的使用
[root@clsn6 awk]# du -sh /* 2>/dev/null|sort -hr
1.1G /usr
214M /lib
120M /var
109M /root
38M /boot
···
1.4.2 统计流量使用的命令
[root@clsn6 ~]# yum install htop iotop iftop atop nethogs -y
# iftop 总体流量使用情况
# nethogs 显示进行级别的流量使用
1.4.3 其他日志分析方法
awstat,piwiki,elk
1.5 参考文献
AWK常用技巧的更多相关文章
- awk --- 常用技巧
一.每隔几行取出一个数,输出到另外一个文件 awk '{ if (NR % 9 ==1) {print NR, " => ", $0 } }' kp.txt > xy_ ...
- 【shell 大系】Linux Shell常用技巧
在最近的日常工作中由于经常会和Linux服务器打交道,如Oracle性能优化.我们数据采集服务器的资源利用率监控,以及Debug服务器代码并解决其效率和稳定性等问题.因此这段时间总结的有关Linux ...
- Linux Shell常用技巧(目录)
Linux Shell常用技巧(一) http://www.cnblogs.com/stephen-liu74/archive/2011/11/10/2240461.html一. 特殊文件: /dev ...
- Shell 常用技巧
Shell 常用技巧 echo $RANDOM | cksum | cut -c - openssl rand -base64 | cksum | cut -c - date +%N | cut -c ...
- SHELL脚本编程的常识和VI常用技巧
来源:http://mprc.pku.edu.cn/mentors/training/TrainingCourses/material/ShellProgramming.HTM#_Toc3751808 ...
- Linux Shell编程之常用技巧
前言 本文集中介绍了bash编程中部分高级编程方法和技巧.通过学习本文内容,可以帮你解决以下问题: 1.bash可以网络编程么? 2..(){ .|.& };. 据说执行这些符号可以死机,那么 ...
- [转帖]Linux Shell常用技巧(五)
Linux Shell常用技巧(五) https://zhuanlan.zhihu.com/p/73451771 1. 变量:在awk中变量无须定义即可使用,变量在赋值时即已经完成了定义.变量的类型可 ...
- 学习笔记:CentOS7学习之二十五:shell中色彩处理和awk使用技巧
目录 学习笔记:CentOS7学习之二十五:shell中色彩处理和awk使用技巧 25.1 Shell中的色彩处理 25.2 awk基本应用 25.2.1 概念 25.2.2实例演示 25.3 awk ...
- oracle存储过程常用技巧
我们在进行pl/sql编程时打交道最多的就是存储过程了.存储过程的结构是非常的简单的,我们在这里除了学习存储过程的基本结构外,还会学习编写存储过程时相关的一些实用的知识.如:游标的处理,异常的处理,集 ...
随机推荐
- js----jquery和js的区别
1.在htlm页面中引入jquery文件后,想获取<input>输入框的数据 <input type='text' id = 'username>' var text = $( ...
- python 全栈开发,Day75(Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件)
昨日内容回顾 基于对象的跨表查询 正向查询:关联属性在A表中,所以A对象找关联B表数据,正向查询 反向查询:关联属性在A表中,所以B对象找A对象,反向查询 一对多: 按字段:xx book ----- ...
- Ext.js入门:Window对象与FormPanel(六)
一:Ext.Window类 二:Ext.Window类实例 三:Ext.FormPanel类 四:Ext.FormPanel类实例 1.类Ext.Window 包: Ext 定义的文件 Windo ...
- struts2之OGNL和struts2标签库和ValueStack对象
OGNL简介: (1)OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. struts2框架默认就支持Ognl表达式语言(所以 ...
- 针对mysql delete删除表数据后占用空间不变小的问题
开发环境 Yii1版本 MySQL PHP5.6.27 前言 物流规则匹配日志表记录订单匹配规则相关日志信息,方便管理员维护和查阅不匹配的订单,四个月时间,该日志表数据就有174G,当前,这么大的数据 ...
- POJ 2318 TOYS (叉乘判断)
<题目链接> 题目大意: 给出矩形4个点和n个挡板俩顶点的位置,这n个挡板将该矩形分成 n+1块区域,再给你m个点的坐标,然你输出每个区域内有几个点. 解题思路: 用叉乘即可简单判断点与直 ...
- POJ 2407 Relatives【欧拉函数】
<题目链接> 题目大意: Given n, a positive integer, how many positive integers less than n are relativel ...
- 对扫描的pdf文件生成目录
很多pdf文件是直接扫描生成的,于是它的内容都是一张张的图片,当然就更没有目录索引了. 有的时候想找某些内容,只能一点点的移动滚动条,非常不方便. 那么有什么方法能生成目录呢? 方法一:使用福昕pdf ...
- Spring框架学习02——Spring IOC 详解
1.Spring IOC的基本概念 IOC(Inverse of Control)反转控制的概念,就是将原本在程序中手动创建对象的控制权,交由Spring框架管理.当某个Java对象(调用者)需要调用 ...
- Luogu
dalao们的博客a http://hzwer.com //Orz %%% https://oi-wiki.org //Orz https://www.cnblogs.com/-guz/p/9 ...