前言

对于一名专业的程序员来说,Linux相关知识是必须要掌握的,其中对于文本的处理更是我们常见的操作,比如格式化输出我们需要的数据,这些数据可能会来源于文本文件或管道符,或者统计文本里面我们需要的数据出现的频次以及总数等等。那么这时候awk就很值得我们去学习了。

正文

在Linux中,awk、sed、grep被称为“三剑客”,都跟文本操作有关,那他们各自有什么特点呢?

grep:适合用于单纯的查找与匹配。
sed:适合修改匹配到的文本。
awk:适合对文本进行复杂的格式化处理。

所以awk是一种文本处理的编程工具语言,它会扫描输入数据的每一行,若与当前的pattern匹配,则执行对应的动作,若不匹配或者当前行的动作已执行完成的话则会继续下一行的处理,直到数据读取完成。

基本用法

awk基本语法
awk [option] 'pattern{action}' files

//awk 关键字
//[option] 可以省略的一些参数
//'pattern{action}' pattern 是匹配的条件,可省略。action是具体执行的动作。
//files 是我们操作的文件,可多文件操作。

  

awk典型用法

awk '{
BEGIN{action ...} //执行前语句
{action...} //匹配处理每行数据
END{action...} //执行后语句
}'

  


awk内置变量
变量 作用
FS 输入字段分割符,默认空白字符
OFS 输出字段分割符,默认空白字符
RS 输入记录也就是行数据分隔符,默认换行符
ORS 输出记录也就是行数据分隔符,默认换行符
NF 当前行被分割成多少个字段的数量
NR 当前的行号,从1开始,在多文件中该值也会累加
FNR 当前的行号,从1开始,与NR不同,它是对应各自的文件累加
FILENAME 当前的文件名
$0 当前行数据
$1 ~ $n 获取该行记录的第N个字段

示例:

[root@wangzh awkdemo]# cat /etc/passwd

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
...

  

//利用FS修改输入字段分割符,然后输出行号以及第1第7个字段的值
[root@wangzh awkdemo]# awk 'BEGIN{FS=":"} {print NR,$1,$7}' /etc/passwd
1 root /bin/bash
2 bin /sbin/nologin
3 daemon /sbin/nologin
4 adm /sbin/nologin
...

  

//跟上一个例子的区别,添加了标题的输出,修改了输出字段的分隔符为"-"
[root@wangzh awkdemo]#awk 'BEGIN{FS=":";print "Result Title"} {print NR,$1}' OFS="-" /etc/passwd
Result Title
1-root
2-bin
3-daemon
4-adm
...

  


运算符与正则

这块内容的话,跟我们大多数编程语言都比较相似,大伙可以横向对比一下,对于刚接触的同学可以会理解一点。

算术运算符:==,>,<,!=,>=,<=,+,-

逻辑运算符:&&,||

正则:

  • /regex/ 该行内容匹配上正则就执行动作

  • ! /regex/ 该行内容未匹配上正则就执行动作

  • $1 ~ /regex/ 只在第一个字段匹配正则

  • $1 !~ /regex/ 第一个字段不匹配该正则

案例:

//'-F:' 是定义输入字段分割字符的另一种方法,这个匹配第一个字段包含'root'的信息
[root@wangzh awkdemo]# awk -F: '$1 ~ /root/ {print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
dockerroot:x:994:991:Docker User:/var/lib/docker:/sbin/nologin

  

//输出第一行到第三行的数据
[root@wangzh awkdemo]# ip addr | awk 'NR>=1 && NR<=3 {print}'
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo

  

if/for/while
if(condi1){action1} else if(condi2){action2} else{action3}

---

for(i=1;i<=NR;i++){
action1;
action2;
...
} --- while(condi){
action1;
...
} 可以看到,用法几乎跟很多编程语言是一致的,下面给出一个简单的示例。 [root@wangzh awkdemo]# cat t1.log
1 aa
3 bb
10 cc
9 dd
5 ee --- //判断每行第一个字段是否是3-9之间的数字,然后输出对应的结果
[root@wangzh awkdemo]# awk '{if($1 ~ /[3-9]/){print "yes"} else {print "no"}}' t1.log
no
yes
no
yes
yes

  

内置函数

在awk中,内置函数也不少,帮助我们封装了一些字符操作、数学操作等,具体的用法还需各位查阅帮助手册,下面就先介绍一下比较常用的 sub() 函数的用法。

参考:http://www.cnblogs.com/chengmo/archive/2010/10/08/1845913.html

sub( Ere, Repl, [ string ] )

string参数是需要处理的字符串,默认是$0也就是当前行
Ere正则匹配的字符串用Repl的字符串来替换

[root@wangzh awkdemo]# awk 'BEGIN{info="this is a test2019test!";sub(/[0-9]+/,"!",info);print info}'
this is a test!test!

  

实战案例

统计文本中关键字出现的次数

[root@wangzh awkdemo]# cat data.txt
ID NAME
1 xiaom
2 zsan
3 lisi
4 lisi
5 lisi
6 xiaom
7 lisi
8 xiaom
9 xiaoh
10 zsan


[root@wangzh awkdemo]# awk 'BEGIN{print "Statistics Result >>>>>"} {if(FNR>1){result[$2]+=1}} END{for(i in result){print i,"count:"result[i]} {print "over >>>>"}}' data.txt
Statistics Result >>>>>
xiaoh count:1
xiaom count:3
zsan count:2
lisi count:4
over >>>>

  

结语

本篇文章的目的是让没接触这块内容的同学对文本处理有一个感性的认识,对于掌握awk绝对不是只看就可以学会的,必须要自己动手实践起来,遇到问题多查手册,相信很快你也是一个文本处理高手。

---------------------------------------------------------

公众号博文同步Github仓库,有兴趣的朋友可以帮忙给个Star哦,码字不易,感谢支持。

https://github.com/PeppaLittlePig/blog-wechat

推荐阅读

Java日志正确使用姿势

Java异常处理最佳实践及陷阱防范

论JVM爆炸的几种姿势及自救方法

看完本文有收获?请转发分享给朋友吧

关注「深夜里的程序猿」,分享最干的干货

程序猿必知必会Linux命令之awk的更多相关文章

  1. Android程序员必知必会的网络通信传输层协议——UDP和TCP

    1.点评 互联网发展至今已经高度发达,而对于互联网应用(尤其即时通讯技术这一块)的开发者来说,网络编程是基础中的基础,只有更好地理解相关基础知识,对于应用层的开发才能做到游刃有余. 对于Android ...

  2. .NET程序员项目开发必知必会—Dev环境中的集成测试用例执行时上下文环境检查(实战)

    Microsoft.NET 解决方案,项目开发必知必会. 从这篇文章开始我将分享一系列我认为在实际工作中很有必要的一些.NET项目开发的核心技术点,所以我称为必知必会.尽管这一系列是使用.NET/C# ...

  3. 迈向高阶:优秀Android程序员必知必会的网络基础

    1.前言 网络通信一直是Android项目里比较重要的一个模块,Android开源项目上出现过很多优秀的网络框架,从一开始只是一些对HttpClient和HttpUrlConnection简易封装使用 ...

  4. python网络爬虫,知识储备,简单爬虫的必知必会,【核心】

    知识储备,简单爬虫的必知必会,[核心] 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌 ...

  5. 读《MySQL必知必会》我学到了什么?

    前言 最近在写项目的时候发现自己的SQL基本功有些薄弱,遂上知乎查询MYSQL关键字,期望得到某些高赞答案的指点,于是乎发现了 https://www.zhihu.com/question/34840 ...

  6. 读书笔记--SQL必知必会--建立练习环境

    书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL in 10 Minutes - Fourth Edition> MyS ...

  7. SQL 必知必会

    本文介绍基本的 SQL 语句,包括查询.过滤.排序.分组.联结.视图.插入数据.创建操纵表等.入门系列,不足颇多,望诸君指点. 注意本文某些例子只能在特定的DBMS中实现(有的已标明,有的未标明),不 ...

  8. 2015 前端[JS]工程师必知必会

    2015 前端[JS]工程师必知必会 本文摘自:http://zhuanlan.zhihu.com/FrontendMagazine/20002850 ,因为好东东西暂时没看懂,所以暂时保留下来,供以 ...

  9. [ 学习路线 ] 2015 前端(JS)工程师必知必会 (2)

    http://segmentfault.com/a/1190000002678515?utm_source=Weibo&utm_medium=shareLink&utm_campaig ...

  10. Visual Studio 使用及调试必知必会

    原文:Visual Studio 使用及调试必知必会   一:C# CODING 技巧 1:TODO 然后 CTRL + W + T,打开任务列表,选中 Comments,就会显示所有待做的任务 2: ...

随机推荐

  1. Python并发编程之创建多线程的几种方法(二)

    大家好,并发编程 进入第二篇. 今天的内容会比较基础,主要是为了让新手也能无障碍地阅读,所以还是要再巩固下基础.学完了基础,你们也就能很顺畅地跟着我的思路理解以后的文章. 本文目录 学会使用函数创建多 ...

  2. java 一维数组

    数组的概念?有什么特点? 数组是指一组数据的集合,数组中的每个数据被称作元素.在数组中可以存放任意类型的元素,但同一个数组里存放的元素类型必须一致. 一维数组的定义格式? 数据类型[]   名称  = ...

  3. Vlan 原理

    VLAN(Virtual LAN),翻译成中文是"虚拟局域网".LAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算机构成的企业网络.VLAN所指的LAN特指使用路由 ...

  4. 用redis的scan命令代替keys命令,以及在spring-data-redis中遇到的问题

    摘要 本文主要是介绍使用redis scan命令遇到的一些问题总结,scan命令本身没有什么问题,主要是spring-data-redis的问题. 需求 需要遍历redis中key,找到符合某些pat ...

  5. mysql explain rows理解

    在MySQL性能调试中,常常使用EXPLAIN解释MySQL执行计划,从而用来估算性能耗时.其中,rows用来表示在SQL执行过程中会被扫描的行数,该数值越大,意味着需要扫描的行数,相应的耗时更长.但 ...

  6. Spring Cloud微服务系统下的数据一致性探讨

    我想这个问题需要根据自己的系统具体架构来分别讨论,这边拿一个车联网的系统举例. 拆除GPS这个功能接口需要分几个步骤实现(不涉及数据更新的步骤略去了): ①更改GPS设备状态(设备管理服务) ②更改工 ...

  7. PHP入门小练习

    1.编写字符串检查函数,判断一个字符串是否为有效电话号码.要求:手机号码的长度为11位的数字,固定电话为开头三或四个数字后跟一个短横线后接8位数字. <? function isTel($tel ...

  8. jquery 获取jquery对象的标签类型

    //jquery 对象 $("#"+控件id)[0] //查看控件类型  $("#"+控件id)[0].type 实例1: < select id=&qu ...

  9. SSM-SpringMVC-30:SpringMVC中InitBinder的骇客级优化

     ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 上篇博客利用initbinder做了局部的日期类型转换,但是兼容性不要,只支持yyyy-MM-dd这种,所以 ...

  10. form 表单提交返回值问题

    form不比ajax,即使后台返回值后,在页面也不知道怎么去取值判断提交状态.所以前几天结合网上资料整了一个小案例,需要用到ajaxSubmit,即通过ajax来提交表单,好处在于可以在任何情况下进行 ...