转自:http://blog.csdn.net/guoer9973/article/details/44650729

awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息,awk处理过程: 依次对每一行进行处理,处理完成后统计然后输出。

命令格式:

awk命令形式: 
awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file 
[-F|-f|-v] 大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value

’ ’ 引用代码块 
BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符 
// 匹配代码块,可以是字符串或正则表达式 
{} 命令代码块,包含一条或多条命令 
; 多条命令使用分号分隔 
END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

特殊要点: 
0表示整个当前行1 每行第一个字段 
NF 字段数量变量 
NR 每行的记录号,多文件记录递增 
FNR 与NR类似,不过多文件记录不递增,每个文件都从1开始 
\t 制表符 
\n 换行符 
FS BEGIN时定义分隔符 
RS 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入) 
~ 匹配,与==相比不是精确比较 
!~ 不匹配,不精确比较 
== 等于,必须全部相等,精确比较 
!= 不等于,精确比较 
&&  逻辑与 
|| 逻辑或 
+ 匹配时表示1个或1个以上 
/[0-9][0-9]+/ 两个或两个以上数字 
/[0-9][0-9]*/ 一个或一个以上数字 
FILENAME 文件名 
OFS 输出字段分隔符, 默认也是空格,可以改为制表符等 
ORS 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕 
-F’[:#/]’ 定义三个分隔符

下面我们来看怎么使用吧,手把手教你用起来:

1,打印日志part01中的内容。

liuhanlindemac:Downloads yishiyaonie$ awk '{print}' part01

2,打印相同行数多的a行。

liuhanlindemac:Downloads yishiyaonie$ awk '{print "a"}' part01

3,-F定义分隔符。默认是用空格来作为分隔符的。

liuhanlindemac:Downloads yishiyaonie$ awk -F'【】' '{print $1}' part01

【】处可以是任意的字符。作为段停的一个标记。很好用欧。

4,将字段分行打印。

liuhanlindemac:Downloads yishiyaonie$ awk  '{print $1;print $6}' part01

5,输出数据格式化

  • 1liuhanlindemac:Downloads yishiyaonie$ awk '{print $1,$3,$4}' OFS='\t' part01

6,awk调用脚本对文件执行操作。

脚本script代码:

BEGIN{
FS=":"
}
{print $1}
liuhanlindemac:Downloads yishiyaonie$ awk -f script part01

7,awk自定义输出:

liuhanlindemac:Downloads yishiyaonie$ awk -F' '  '{print "username:"$1 "\t\t uid: " $4}' part01

awk  '{print $1 $3}'  part01           //$1与$3相连输出,不分隔
awk '{print $1,$3}' part01 //多了一个逗号,$1与$3使用空格分隔
awk '{print $1 " " $3}' part01 //$1与$3之间手动添加空格分隔

8,awk对一条记录字段数量做判断的输出。

awk  '{print $NF}' part01           //将每行第NF个字段的值打印出来
awk 'NF==4 {print }' part01 //显示只有4个字段的行
awk 'NF>2{print $0}' part01 //显示每行字段数量大于2的行

9,awk对行的处理:

awk '{print NR,NF,$NF,"\t",$0}' part01 //依次打印行号,字段数,最后字段值,制表符,每行内容
awk 'NR==5{print}' part01 //显示第5行
awk 'NR==5 || NR==6{print}' part01 //显示第5行和第6行
awk 'NR!=1{print}' part01 //不显示第一行

10,匹配字符处理:

//纯字符匹配   !//纯字符不匹配   ~//字段值匹配    !~//字段值不匹配   ~/a1|a2/字段值匹配a1或a2 
awk '/183.198.46.6/' part01

awk  '/mail/,/mysql/{print}' /etc/passwd         //区间匹配
awk '/[2][7][7]*/{print $0}' /etc/passwd //匹配包含27为数字开头的行,如27,277,2777...
awk '$1~/mail/{print $1}' /etc/passwd //$1匹配指定内容才显示
awk '{if($1~/mail/) print $1}' /etc/passwd //与上面相同
awk '$1!~/mail/{print $1}' /etc/passwd //不匹配

11,IF语句,必须用在{}中,且比较内容用()扩起来

awk  '{if($1~/mail/) print $1}' /etc/passwd                                       //简写
awk '{if($1~/mail/) {print $1}}' /etc/passwd //全写
awk '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd //if...else...

12, 条件表达式 == != > >=

awk '$1=="183.198.46.6"{print $4}' part01
awk '{if($1=="mysql") print $3}' /etc/passwd //与上面相同
awk '$1!="mysql"{print $3}' /etc/passwd //不等于
awk '$3>1000{print $3}' /etc/passwd //大于
awk '$3>=100{print $3}' /etc/passwd //大于等于
awk '$3<1{print $3}' /etc/passwd //小于
awk '$3<=1{print $3}' /etc/passwd //小于等于

13,逻辑运算符 && ||

awk '$1~/183.198.46.6/ && $4~/2015:19:14:40/ {print$7}' part01
awk '$1~/mail/ && $3>8 {print }' part01 //逻辑与,$1匹配mail,并且$3>8
awk '{if($1~/mail/ && $3>8) print }' /etc/passwd
awk '$1~/mail/ || $3>1000 {print }' /etc/passwd //逻辑或
awk '{if($1~/mail/ || $3>1000) print }' /etc/passwd

14,数值运算

awk  '$3 > 100' /etc/passwd
awk '$3 > 100 || $3 < 5' /etc/passwd
awk '$3+$4 > 200' /etc/passwd
awk '/mysql|mail/{print $3+10}' /etc/passwd //第三个字段加10打印
awk '/mysql/{print $3-$4}' /etc/passwd //减法
awk '/mysql/{print $3*$4}' /etc/passwd //求乘积
awk '/MemFree/{print $2/1024}' /proc/meminfo //除法
awk '/MemFree/{print int($2/1024)}' /proc/meminfo //取整

15,输出分隔符OFS

 awk '$1~/183.198.46.6/||NR==1  {print NR ,$1,$4,$7}' OSF='\t' part01
//输出字段1匹配183.198.46.6的行,其中输出每行行号,字段1,4,7,并使用制表符分割字段
主要是为了显示好看。

16, 输出处理结果到文件

使用重定向进行输出       awk '$1~/183.198.46.6/||NR==1  {print NR ,$1,$4,$7}' OSF='\t' part01 >1.txt
在命令代码块中直接输出 awk 'NR!=1{print > "./fs"}'

17,格式化输出

awk '{printf "%-8d %-8s %-10s\n",$1,$2,$3}' part01
printf表示格式输出
%格式化输出分隔符,-8长度为8个数字,s表示字符串类型,打印每行前三个字段,指定第一个字段输出字符串类型(长度为8),第二个字段输出字符串类型(长度为8),第三个字段输出字符串类型(长度为10)
netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s \n",$1,$2,$3}'
netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-3s %-10s %-10s %-10s \n",NR,$1,$2,$3}'

18,IF语句

awk '{if ($1~/183.198.46.6/) {print "ok"} else {print "nop"}}' part01
awk 'BEGIN{a=0;b=0} {if($1~/183.198.46.6/) {a++;print "ok"} else {b++;print "nop"}} END {print a,b} OSF='\t\t'' part01 //ID大于100,A加1,否则B
awk '{if($3<100) next; else print}' /etc/passwd //小于100跳过,否则显示
awk 'BEGIN{i=1} {if(i<NF) print NR,NF,i++ }' /etc/passwd
awk 'BEGIN{i=1} {if(i<NF) {print NR,NF} i++ }' /etc/passwd
另一种形式
awk '{print ($3>100 ? "yes":"no")}' /etc/passwd
awk '{print ($3>100 ? $3":\tyes":$3":\tno")}' /etc/passwd

19,while 语句

awk  'BEGIN{i=1} {while(i<NF) print NF,$i,i++}' part01

20,数组

awk 'NR!=1 {a[$1]++} END {for (i in a) {print a[i],"\t",i}}' part01

awk 'NR!=1{a[$6]++} END{for (i in a) printf "%-20s %-10s %-5s \n", i,"\t",a[i]}'


按照第一个字段做汇总,第一个字段的重复数量统计。

好了,到目前为止语法差不多了,我们需要更多的实践来运用awk这个强大的文本统计工具。

应用1
awk -F: '{print NF}' helloworld.sh //输出文件每行有多少字段
awk -F: '{print $1,$2,$3,$4,$5}' helloworld.sh //输出前5个字段
awk -F: '{print $1,$2,$3,$4,$5}' OFS='\t' helloworld.sh //输出前5个字段并使用制表符分隔输出
awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS='\t' helloworld.sh //制表符分隔输出前5个字段,并打印行号 应用2
awk -F'[:#]' '{print NF}' helloworld.sh //指定多个分隔符: #,输出每行多少字段
awk -F'[:#]' '{print $1,$2,$3,$4,$5,$6,$7}' OFS='\t' helloworld.sh //制表符分隔输出多字段 应用3
awk -F'[:#/]' '{print NF}' helloworld.sh //指定三个分隔符,并输出每行字段数
awk -F'[:#/]' '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}' helloworld.sh //制表符分隔输出多字段 应用4
计算/home目录下,普通文件的大小,使用KB作为单位
ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",sum/1024,"KB"}'
ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",int(sum/1024),"KB"}' //int是取整的意思 应用5
统计netstat -anp 状态为LISTEN和CONNECT的连接数量分别是多少
netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s \n", i," ",sum[i]}' 应用6
统计/home目录下不同用户的普通文件的总数是多少?
ls -l|awk 'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s \n",i," ",sum[i]}'
mysql 199
root 374
统计/home目录下不同用户的普通文件的大小总size是多少?
ls -l|awk 'NR!=1 && !/^d/{sum[$3]+=$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s \n",i," ",sum[i]/1024/1024,"MB"}' 应用7
输出成绩表
awk 'BEGIN{math=0;eng=0;com=0;printf "Lineno. Name No. Math English Computer Total\n";printf "------------------------------------------------------------\n"}{math+=$3; eng+=$4; com+=$5;printf "%-8s %-7s %-7s %-7s %-9s %-10s %-7s \n",NR,$1,$2,$3,$4,$5,$3+$4+$5} END{printf "------------------------------------------------------------\n";printf "%-24s %-7s %-9s %-20s \n","Total:",math,eng,com;printf "%-24s %-7s %-9s %-20s \n","Avg:",math/NR,eng/NR,com/NR}' test0

日志查询系统

#! /bin/bash
echo "example:" "--------./log.sh 404 2015-04-01 REQ_IO 15-00---------------------------------------------------------------------------------"
code=$1
echo "the code is ${code} "
date=$2
echo "the date is ${date}"
operation=$3
echo "the operation is ${operation}"
time=$4
echo "the time is ${time}"
if [ "$operation" = "REQ_IO" -a "$code" = "401" ];
then
echo "searching code 401............waiting for a while" hdfs dfs -cat /flume/${date}/${operation}/${time}/*.log|awk '{if ($7~/401/) {a[$5" UID:" substr($0, index($0, "uid") + 5, 10)]++}} END {for (i in a) {print a[i],i}}'| sort -rn | head
fi if [ "$operation" = "REQ_IO" -a "$code" = "404" ];
then
echo "searching code 404............waiting for a while"
hdfs dfs -cat /flume/${date}/${operation}/${time}/*.log|awk '{if ($7~/404/) {a[$5]++}} END {for (i in a) {print a[i],i}}'| sort -rn | head
fi


部分地方的空格一定要注意,主要是一些书写格式规范和用法的注意点我这里都标注出来了。还有就是第四和第五的用法,将一条记录中的若干内容拼接到一起来作为一个数据项。这个是不是很厉害呢。 
关于substr以及index的用法请参考:linux awk 内置函数详细介绍(实例) 
http://www.cnblogs.com/chengmo/archive/2010/10/08/1845913.html

 

linux的awk命令解读的更多相关文章

  1. linux中awk命令(最全面秒懂)

    目录 一:linux中awk命令 1.awk命令简介 2.awk作用 3.awk的语法格式 4.解析awk使用方法 5.参数 6.awk的生命周期 二:awk中的预定义变量 三:awk运行处理规则的执 ...

  2. linux中awk命令详解(最全面秒懂)

    一:linux中awk命令 1.awk命令简介 AWK 是一种处理文本文件的语言,是一个强大的文本分析工具. 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinber ...

  3. linux 常用awk命令

    linux awk命令详解awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每 ...

  4. Linux系统——awk命令

    awk命令不仅仅是Linux系统的命令,也是一种编程语言,用来处理数据和生成报告(Exel),处理的数据可以是一个或多个文件(标准输入和管道获取标准输入).可在命令行上编辑操作,也可以写成awk程序运 ...

  5. Linux的awk命令

    简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...

  6. Linux之awk命令详解

    简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...

  7. linux下awk命令详解

    简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...

  8. Linux学习awk命令

    awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各 ...

  9. linux之awk命令获取最后一列

    统计分析中经常用的awk命令,其中用的最多的还是切分 cat  test | awk -F',' '{print $1,$2} 能够很好的将记录按照需要切分开, 但是如何获取最后一列呢? 可以使用aw ...

随机推荐

  1. pyqt5-UDP消息发送

    使用pyqt5做了一个发送UDP消息的客户端. 项目的完整代码已上传到 github 很简单的,只是用来向某个地址发送UPD消息.这个后面会用到新的功能也会更新.这里贴一下qt5做界面的代码,跟qt4 ...

  2. JavaScript高级 面向对象(12)--引用类型值类型作为参数传递的特性

    说明(2017-4-2 18:27:11): 1. 作为函数的参数,就是将函数的数据拷贝一份,传递给函数的定义中的参数. 函数foo()在调用的时候,做了两件事: (1)函数在调用的时候,首先需要将参 ...

  3. iOS开发如何在一个透明视图上添加不透明的子控件

    相信很多同学都会遇到过这个问题, 当我们弹出一个半透明的遮盖层时, 又想在遮盖层上加一些子视图, 这个时候如果你的遮盖层设置了alpha属性,  你会惊讶的发现, 加载遮盖层上的所有子控件都是透明了, ...

  4. curl Array to string conversion 错误

    0x00 故障 由于GuzzleHttp在iis上使用错误,于是开始替换其为Unirest,没想到发送了一个curl Array to string conversion 错误 0x01 原因 跟踪调 ...

  5. [转]Java中BigDecimal的使用

    原文地址:https://blog.csdn.net/cen_s/article/details/76472834 在日常开发中我们经常会碰到小数计算,而小数直接计算的话会出现一些小小的错误,如下 S ...

  6. 无法将 lambda 表达式 转换为类型“System.Delegate”,因为它不是委托类型

    今天写winform的时候遇到一个问题,提示: 无法将 lambda 表达式 转换为类型“System.Delegate”,因为它不是委托类型, 主要是为了在子线程中更新UI线程,在wpf中同样的写法 ...

  7. .net 4中使用 dynamic,将json字符串转成对象的 万能方法。

    在.net 4中增加了对弱类型的支持.为和弱类型的对象进行数据交换提供了方法.我们常常会遇到将json字符串转成对象的情景,虽然可以使用 JavaScriptSerializer 或者 DataCon ...

  8. ashx session 赋值 获取

    ashx想获取session值 需要继承 IRequiresSessionState接口 ExcelHelper : IHttpHandler, IRequiresSessionState publi ...

  9. jQuery(五):文本操作

    text()可以获取或设置元素的文本内容.例如: 示例: <!DOCTYPE html> <html lang="en"> <head> < ...

  10. Entity Framework应用:根据实体的EntityState状态实现增删改查

    在上一篇文章中,我们讲解了使用EF实现简单的增删改成,在这篇文章中我们使用实体的EntityState状态来优化数据的增删改查. 一.修改数据 上篇文章中的修改数据的方法是EF官方推荐的方式,即先查询 ...