为什么要用
对于我们后端人员来说,经常需要去服务器查找日志信息,排查详细错误信息或者监控服务器,强大如grep已经可以满足绝大部分需求,但是awk和sed这两个强大的命令工具也很好用,下面记录一下这两个工具如何使用。
AWK
引自百科:
AWK是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人阿尔佛雷德·艾侯、彼得·温伯格和布莱恩·柯林汉姓氏的首个字母)的最大功能取决于一个人所拥有的知识。awk经过改进生成的新的版本nawk,gawk,现在默认linux系统下日常使用的是gawk,用命令可以查看正在应用的awk的来源(ls -l /bin/awk )
开始使用
先查询一份网络数据,使用重定向保存下来:
简单使用,输出第1列和第4列:
- 其中单引号中的被大括号括起来的就是awk的语句,注意,其只能被单引号包含。
- 其中的$1….$n表示第几列。($0表示整个行)
|
|
awk可以格式化输出,用过C和Java等语系的应该都挺熟悉:
|
|
过滤记录
可以对其中某个或某些字段进行判断,使用比较判断符即可(通过与或非进行连接)
比较判断符:==、!=、>=、>=、>、<
连接符:|| 、&&、 !
例如筛选出第三列大于0的数据行:
|
|
如果需要打印行号的话,可以使用内建变量NR:
内建变量
内建变量相当于该程序的内置变量,可以直接拿来使用:
变量 | 变量含义 |
---|---|
$0 | 当前记录(这个变量存放当前行的内容 |
$1~$n | 当前记录的第n个字段,字段由分隔符FS分割 |
FS | 输入字段分隔符,默认是空格或Tab |
NF | 当前记录中的字段个数,就是有多少列 |
NR | 已经读出的记录数,就是行号,从1开始,如果有多个文件的话,这个值也是不断累加中 |
FNR | 当前记录数,与NR不同的是,这个值是各自文件自己的行号 |
RS | 输入的记录分隔符,默认是换行符 |
OFS | 输出字段分隔符,默认也是空格 |
ORS | 输出的记录分隔符,默认是换行符 |
FILENAME | 当前输入文件的名字 |
例如有些文件的分隔符不是空格,而是其他,可以自定义分隔符:
|
|
上面命令等价于:(-F的意思就是制定分隔符)
注意:如果要制定多个分隔符,可以使用:
awk -F ‘[;:]’
自定义输出字段的分隔符(例如制表符\t):
字符串匹配
可以跟grep一样,匹配相关字符:
还可以精确匹配某个字段:
|
|
其中:~表示模式开始,两个/中间是模式,相当于进行正则表达式的匹配(同样道理,在正则表达式前使用!可以进行取反操作,这里就不展示了)
拆分文件
指定某列为分类符,使用重定向就可以导出到不同的文件中,例如下列语句通过第六列进行分割:
|
|
可以查看各自文件,发现已经是分类后的结果:
同样,可以指定某些列进行输出,也可以使用复杂的表达式(例如if-else-if语句,awk是个脚本解释器)
|
|
注意,if-else语句要在同一个花括号{}里~
统计
下面语句是用来统计以.txt为后缀的文件总大小:
|
|
同样,可以在统计时使用数据,分开统计不同项目的总数
用来统计网络状态
用来统计每个用户的进程占了多少内存:(通过ps -aux查看,第六列表示占用的内存)
awk脚本
有两个关键字需要注意BEGIN和END:
- BEGIN{这里放的是,执行前的语句}
- END{这里放的是,执行后的语句}
- {这里放的是处理每一行时要执行的语句}
例如下面例子,简单统计行数:(只是简单介绍一下脚本如何写,更多定制化的可以小伙伴去探索~)
执行脚本(也可以使用./cal.awk netstat.txt)
结合环境变量
通过使用-v参数和ENVIRON,与环境变量打交道:
|
|
当然,在使用环境变量的时候,记得要export该变量
SED命令
全称是:Stream EDitor,功能月awk类似,差别在于,sed比awk简单一点,常用于字符替换。匹配符可以使用正则表达式进行匹配,所以想要用更强大的功能,需要去了解一下正则表达式~
使用S命令替换
使用以下文本进行测试
S命令介绍:
s表示替换命令,/I/表示匹配I, /John/表示将前面的I替换成Json,/g表示进行所有行上所有字符的匹配(注意,匹配时区分大小写)
|
|
这样只是对于输出流的字符进行替换,原文本的数据不会改变,有两种方法可以修改输出流的数据:
使用重定向 >
1sed "s/I/John/g" self.txt > other.txt使用-i参数
1sed -i "s/I/John/g" self.txt
可以在每一行最前面加数据:(例如将文本开头加个#字符)
可以在行末尾加一些数据:(例如加分割符或者结束符)
使用正则表达式去掉html中的tags:
Html文本为:
替换脚本:
可以指定替换特定行号的文本,多行间使用逗号(,)进行连接:(例如下面只替换第5到第8行的数据)
测试文本:
指定只替换每一行第一个出现的字符:
指定替换每一行第二个及第二个之后的字符:
多个匹配
如果需要在一次命令中,匹配多个模式,可以写多个匹配表达式,通过分号;进行分割:(例如下面将1,2行的This替换成That,3到最后一行的is替换成are)
|
|
可以使用&,用来当做被匹配的变量,然后在匹配的变量前后加一些内容:
圆括号匹配
圆括号括起来的正则表达式所匹配的字符串可以当成变量来使用,其中,\1表示第一个匹配,\2表示第二个匹配,以此类推)
|
|
正则表达式博大精深,每次都是学到用时方恨少!
N命令
这条命令会将下一行的内容送入缓存区,两行并成一行进行匹配:
(例如下面的命令,两行合成一行后,两行之间的换行符\n被替换成空格,所以输出结果,原偶数行与奇数行合并)
a命令和i命令
a:表示append,在某行后面进行追加:
i:表示insert,在某行之前进行插入:
可以进行匹配,然后在匹配行后面进行追加或者之前插入数据:
c命令
C命令:替换命令,将匹配到的行替换掉
单行替换:
多行替换
或者匹配行进行替换:
d命令
d命令:delete,删除
跟上面的替换c命令很类似
单行删除:
多行替换
或者匹配行进行替换:
p命令
p命令:print,打印命令,与grep类似
|
|
命令打包
多个命令可以使用分号进行分开,使用大括号括起来作为嵌套命令:
总结
这两个文档工具如grep一样好用,而且感觉awk的功能更加强大,建议大家去看耗子叔的酷壳博客,干货满满~
参考资料
耗子大神的网站值得一看~