linux 文本分析工具---awk命令(7/1)
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。
awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报 表,还有无数其他的功能。
awk '{pattern + action}' {filenames} |
尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。
awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。
通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。
1.命令行方式
awk [-F field-separator] 'commands' input-file(s)
其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。 2.shell脚本方式
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
可以换成:#!/bin/awk 3.将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)
其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的

awk 赋值运算符:a+5;等价于: a=a+5;其他同类
|
1
2
|
[root@Gin scripts]# awk 'BEGIN{a=5;a+=5;print a}'10 |
awk逻辑运算符:
|
1
2
|
[root@Gin scripts]# awk 'BEGIN{a=1;b=2;print (a>2&&b>1,a=1||b>1)}'0 1 |
判断表达式 a>2&&b>1为真还是为假,后面的表达式同理
awk正则运算符:
|
1
2
|
[root@Gin scripts]# awk 'BEGIN{a="100testaa";if(a~/100/) {print "ok"}}'ok |
|
1
2
|
[root@Gin scripts]# echo|awk 'BEGIN{a="100testaaa"}a~/test/{print "ok"}'ok |
关系运算符:
如: > < 可以作为字符串比较,也可以用作数值比较,关键看操作数如果是字符串就会转换为字符串比较。两个都为数字 才转为数值比较。字符串比较:按照ascii码顺序比较。
|
1
2
3
4
5
|
[root@Gin scripts]# awk 'BEGIN{a="11";if(a>=9){print "ok"}}' #无输出[root@Gin scripts]# awk 'BEGIN{a=11;if(a>=9){print "ok"}}' ok[root@Gin scripts]# awk 'BEGIN{a;if(a>=b){print "ok"}}'ok |
awk 算术运算符:
说明,所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0。
|
1
2
3
4
|
[root@Gin scripts]# awk 'BEGIN{a="b";print a++,++a}'0 2[root@Gin scripts]# awk 'BEGIN{a="20b4";print a++,++a}'20 22 |
这里的a++ , ++a与javascript语言一样:a++是先赋值加++;++a是先++再赋值
三目运算符 ?:
|
1
2
3
4
|
[root@Gin scripts]# awk 'BEGIN{a="b";print a=="b"?"ok":"err"}'ok[root@Gin scripts]# awk 'BEGIN{a="b";print a=="c"?"ok":"err"}'err |
常用 awk 内置变量

注:内置变量很多,参阅相关资料
字段分隔符 FS
FS="\t" 一个或多个 Tab 分隔
|
1
2
3
4
|
[root@Gin scripts]# cat tab.txtww CC IDD[root@Gin scripts]# awk 'BEGIN{FS="\t+"}{print $1,$2,$3}' tab.txtww CC IDD |
FS="[[:space:]+]" 一个或多个空白空格,默认的
|
1
2
3
4
5
6
|
[root@Gin scripts]# cat space.txtwe are studing awk now![root@Gin scripts]# awk -F [[:space:]+] '{print $1,$2,$3,$4,$5}' space.txtwe are [root@Gin scripts]# awk -F [[:space:]+] '{print $1,$2}' space.txtwe are |
FS="[" ":]+" 以一个或多个空格或:分隔
|
1
2
3
4
|
[root@Gin scripts]# cat hello.txtroot:x:0:0:root:/root:/bin/bash[root@Gin scripts]# awk -F [" ":]+ '{print $1,$2,$3}' hello.txtroot x 0 |
字段数量 NF
|
1
2
3
4
5
|
[root@Gin scripts]# cat hello.txtroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologin:888[root@Gin scripts]# awk -F ":" 'NF==8{print $0}' hello.txtbin:x:1:1:bin:/bin:/sbin/nologin:888 |
记录数量 NR
|
1
2
|
[root@Gin scripts]# ifconfig eth0|awk -F [" ":]+ 'NR==2{print $4}' ## NR==2也就是取第2行192.168.17.129 |
RS 记录分隔符变量
将 FS 设置成"\n"告诉 awk 每个字段都占据一行。通过将 RS 设置成"",还会告诉 awk每个地址记录都由空白行分隔。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
[root@Gin scripts]# cat recode.txtJimmy the Weasel100 Pleasant DriveSan Francisco,CA 123456Big Tony200 Incognito Ave.Suburbia,WA 64890[root@Gin scripts]# cat awk.txt#!/bin/awkBEGIN { FS="\n" RS=""}{ print $1","$2","$3}[root@Gin scripts]# awk -f awk.txt recode.txtJimmy the Weasel,100 Pleasant Drive,San Francisco,CA 123456Big Tony,200 Incognito Ave.,Suburbia,WA 64890 |
OFS 输出字段分隔符
|
1
2
3
4
5
6
7
8
9
|
[root@Gin scripts]# cat hello.txtroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologin:888[root@Gin scripts]# awk 'BEGIN{FS=":"}{print $1","$2","$3}' hello.txtroot,x,0bin,x,1[root@Gin scripts]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2,$3}' hello.txtroot#x#0bin#x#1 |
ORS 输出记录分隔符
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
[root@Gin scripts]# cat recode.txtJimmy the Weasel100 Pleasant DriveSan Francisco,CA 123456Big Tony200 Incognito Ave.Suburbia,WA 64890[root@Gin scripts]# cat awk.txt#!/bin/awkBEGIN { FS="\n" RS="" ORS="\n\n"}{ print $1","$2","$3}[root@Gin scripts]# awk -f awk.txt recode.txtJimmy the Weasel,100 Pleasant Drive,San Francisco,CA 123456Big Tony,200 Incognito Ave.,Suburbia,WA 64890 |
awk 正则

正则应用
规则表达式
awk '/REG/{action} ' file,/REG/为正则表达式,可以将$0 中,满足条件的记录送入到:action 进行处理
|
1
2
3
4
5
6
7
8
9
|
[root@Gin scripts]# awk '/root/{print $0}' passwd ##匹配所有包含root的行root:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologin[root@Gin scripts]# awk -F: '$5~/root/{print $0}' passwd ## 以分号作为分隔符,匹配第5个字段是root的行root:x:0:0:root:/root:/bin/bash[root@Gin scripts]# ifconfig eth0|awk 'BEGIN{FS="[[:space:]:]+"} NR==2{print $4}'192.168.17.129 |
布尔表达式
awk '布尔表达式{action}' file 仅当对前面的布尔表达式求值为真时, awk 才执行代码块。
|
1
2
3
4
|
[root@Gin scripts]# awk -F: '$1=="root"{print $0}' passwdroot:x:0:0:root:/root:/bin/bash[root@Gin scripts]# awk -F: '($1=="root")&&($5=="root") {print $0}' passwdroot:x:0:0:root:/root:/bin/bash |
awk 的 if、循环和数组
条件语句
awk 提供了非常好的类似于 C 语言的 if 语句。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
{ if ($1=="foo"){ if($2=="foo"){ print "uno" }else{ print "one" } }elseif($1=="bar"){ print "two" }else{ print "three" }} |
使用 if 语句还可以将代码:
|
1
|
! /matchme/ { print $1 $3 $4 } |
转换成:
|
1
2
3
4
5
|
{ if ( $0 !~ /matchme/ ) { print $1 $3 $4 }} |
循环结构
我们已经看到了 awk 的 while 循环结构,它等同于相应的 C 语言 while 循环。 awk 还有"do...while"循环,它在代码块结尾处对条件求值,而不像标准 while 循环那样在开始处求值。
它类似于其它语言中的"repeat...until"循环。以下是一个示例:
do...while 示例
|
1
2
3
4
5
|
{ count=1do { print "I get printed at least once no matter what" } while ( count !=1 )} |
与一般的 while 循环不同,由于在代码块之后对条件求值, "do...while"循环永远都至少执行一次。换句话说,当第一次遇到普通 while 循环时,如果条件为假,将永远不执行该循环。
for 循环
awk 允许创建 for 循环,它就象 while 循环,也等同于 C 语言的 for 循环:
|
1
2
3
|
for ( initial assignment; comparison; increment ) { code block} |
以下是一个简短示例:
|
1
2
3
|
for ( x=1;x<=4;x++ ) { print "iteration", x} |
此段代码将打印:
|
1
2
3
4
|
iteration1iteration2iteration3iteration4 |
break 和 continue
此外,如同 C 语言一样, awk 提供了 break 和 continue 语句。使用这些语句可以更好地控制 awk 的循环结构。以下是迫切需要 break 语句的代码片断:
|
1
2
3
4
5
|
while 死循环while (1) {print "forever and ever..."}while 死循环 1 永远代表是真,这个 while 循环将永远运行下去。 |
以下是一个只执行十次的循环:
|
1
2
3
4
5
6
7
8
9
|
#break 语句示例x=1while(1) { print "iteration", x if ( x==10 ) { break } x++} |
这里, break 语句用于“逃出”最深层的循环。 "break"使循环立即终止,并继续执行循环代码块后面的语句。
continue 语句补充了 break,其作用如下:
|
1
2
3
4
5
6
7
8
9
10
11
|
x=1while (1) { if ( x==4 ) { x++ continue } print "iteration", x if ( x>20 ) { break } x++} |
这段代码打印"iteration1"到"iteration21", "iteration4"除外。如果迭代等于 4,则增加 x并调用 continue 语句,该语句立即使 awk 开始执行下一个循环迭代,而不执行代码块的其余部分。如同 break 一样,
continue 语句适合各种 awk 迭代循环。在 for 循环主体中使用时, continue 将使循环控制变量自动增加。以下是一个等价循环:
|
1
2
3
4
5
6
|
for ( x=1;x<=21;x++ ) { if ( x==4 ) { continue } print "iteration", x} |
在while 循环中时,在调用 continue 之前没有必要增加 x,因为 for 循环会自动增加 x。
数组
AWK 中的数组都是关联数组,数字索引也会转变为字符串索引
|
1
2
3
4
5
6
7
8
9
10
11
|
{ cities[1]=”beijing” cities[2]=”shanghai” cities[“three”]=”guangzhou” for( c in cities) { print cities[c] } print cities[1] print cities[“1”] print cities[“three”]} |
for…in 输出,因为数组是关联数组,默认是无序的。所以通过 for…in 得到是无序的数组。如果需要得到有序数组,需要通过下标获得。
数组的典型应用
用 awk 中查看服务器连接状态并汇总
|
1
2
3
|
netstat -an|awk '/^tcp/{++s[$NF]}END{for(a in s)print a,s[a]}'ESTABLISHED 1LISTEN 20 |
统计 web 日志访问流量,要求输出访问次数,请求页面或图片,每个请求的总大小,总访问流量的大小汇总
|
1
2
3
4
5
6
7
8
9
|
awk '{a[$7]+=$10;++b[$7];total+=$10}END{for(x in a)print b[x],x,a[x]|"sort -rn -k1";print"total size is :"total}' /app/log/access_logtotal size is :17223021 /icons/poweredby.png 8307614 / 705468 /icons/apache_pb.gif 18608a[$7]+=$10 表示以第 7 列为下标的数组( $10 列为$7 列的大小),把他们大小累加得到$7 每次访问的大小,后面的 for 循环有个取巧的地方, a 和 b 数组的下标相同,所以一条 for 语句足矣 |
常用字符串函数


字符串函数的应用
替换
|
1
2
3
|
awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}' this is a test!test!在 info 中查找满足正则表达式, /[0-9]+/ 用”!”替换,并且替换后的值,赋值给 info 未给 info 值,默认是$0 |
查找
|
1
2
|
awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}'ok #未找到,返回 0 |
匹配查找
|
1
2
|
awk 'BEGIN{info="this is a test2010test!";print match(info,/[0-9]+/)?"ok":"no found";}'ok #如果查找到数字则匹配成功返回 ok,否则失败,返回未找到 |
截取
|
1
2
|
awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}'s is a tes #从第 4 个 字符开始,截取 10 个长度字符串 |
分割
|
1
2
3
4
|
awk 'BEGIN{info="this is a test";split(info,tA," ");print length(tA);for(k in tA){print k,tA[k];}}' 44 test 1 this 2 is 3 a#分割 info,动态创建数组 tA,awk for …in 循环,是一个无序的循环。 并不是从数组下标1…n 开始 |
linux 文本分析工具---awk命令(7/1)的更多相关文章
- linux文本分析利器awk
转 快速理解linux文本分析利器awk 原文链接 杜亦舒 性能与架构 awk是什么 如果工作中需要操作linux比较多,那么awk是非常值得学习的 awk是一个极其强大的文本分析工具,把文件逐行的读 ...
- Linux性能分析工具top命令详解
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,常用于服务端性能分析. top命令说明 [www.linuxidc.com@linuxidc-t-tomcat-1 ...
- Linux 内存分析工具——free命令
在Linux系统经常被用作服务器系统.当服务器内存吃紧的时候,free命令是我们最常使用的内存分析工具. free使用介绍 free命令可以显示Linux系统中空闲的.已用的物理内存及swap内存,及 ...
- Linux 内存分析工具的命令大全介绍
在Linux系统经常被用作服务器系统.当服务器内存吃紧的时候,free命令是我们最常使用的内存分析工具. free使用介绍# free命令可以显示Linux系统中空闲的.已用的物理内存及swap内存, ...
- 文本分析工具awk简单示例
先创建一个文件:vim hi 取第2个字段和第3个字段: awk '{print $2,$3}' hi 注意{}中的,逗号会在输出的时候转变为空格 加入字符说明: 显示整行: 指定字段分隔符: ...
- Linux 之 awk文本分析工具
AWK是一种处理文本文件的语言,是一个强大的文本分析工具.Linux环境中自带. awk调用方法 命令行 awk [-F field-separator] 'commands' input-file( ...
- Linux文本分析命令awk的妙用
基本用法 awk是一个强大的文本分析工具,简单来说awk就是把文件逐行读入,(空格,制表符)为默认分隔符将每行切片,切开的部分再进行各种分析处理 awk命令格式如下 awk [-F field-sep ...
- 《Linux 文本处理》- awk 分析 nginx 日志
废话不多说,简单了解一下 awk - 强大的文本分析工具,也就是分析日志 最常用的就是分析日志了吧,做统计什么,这里也拿 nginx 日志来做分析 1:统计出现次数 - 比如状态码出现次数 - 先直接 ...
- (转)超全整理!Linux性能分析工具汇总合集
超全整理!Linux性能分析工具汇总合集 原文:http://rdc.hundsun.com/portal/article/731.html 出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望, ...
随机推荐
- requirejs学习(一)
requirejs学习(一) 随着网站功能逐渐丰富,网页中的js也变得越来越复杂和臃肿,各种依赖(插件等)也逐渐增多,原有通过script标签来导入一个个的js文件这种方式已经不能满足现在的需求,我们 ...
- MATLAB中的文件类型总结
% ***.m文件 : 脚本文件或者函数文件或者:% ***.mat文件:数据存储文件(二进制文件,可以ASCII码形式保存和加载,% 类似于单行EXCEL表格) ...
- HDU 4970(杭电多校#9 1011题)Killing Monsters(瞎搞)
题目地址:HDU 4970 先进行预处理.在每一个炮塔的火力范围边界标记一个点. 然后对每一个点的伤害值扫一遍就能算出来. 然后在算出每一个点到终点的总伤害值,并保存下来,也是扫一遍就可以. 最后在询 ...
- 【Raspberry Pi】GPIO-发光二极管控制
注意事项: 注意IO脚电流不能大于16mA,3V脚总电流不能大于50mA,所以两个二极管各上拉了400欧左右的电阻 采用物理针脚7和9做控制 其中output参数LOW为接通,HIGH为屏蔽 impo ...
- java编译、编码、语言设置
下面这两行加入,环境变量:特别是gradle在编译文件中含有中文时会遇到一些问题: JAVA_TOOL_OPTIONS -Dfile.encoding=UTF-8 -Duser.language=en ...
- Java安全API
java提供了完整的密码学API,我们可以结合密码学相关的概念来系统的学习这些API. 1.密码学简介(crypto) 密码学通俗来说就是研究如何对信息进行加密和破密,如果不是专门研究信息安全,通常我 ...
- JavaScript------日期和时间戳的相互转换
var date = new Date(); 日期转时间戳 Number(date)或者date.getTime(); //只是转换成了纯数字的时间戳,例如:1498144203861需要转换才能使用 ...
- hdu1814(2-SAT)
2-SAT 求出可能的解,但是这个解要是字典序最小的,所以只能采用2-SAT基本思想来解. 从小到大开始,对一个可能的点染色,染为1,然后dfs其所有能到达的点,如果其中出现一个已经标号为-1的话,那 ...
- [HackerRank] The Longest Common Subsequence
This is the classic LCS problem. Since it requires you to print one longest common subsequence, just ...
- 160624、Spark读取数据库(Mysql)的四种方式讲解
目前Spark支持四种方式从数据库中读取数据,这里以Mysql为例进行介绍. 一.不指定查询条件 这个方式链接MySql的函数原型是: 1 def jdbc(url: String, table: S ...