awk简介

awk是一种使用方便且表现力很强的编程语言,它可以应用在多种不同的计算与数据处理任务中。由于awk天生提供对文件中文本分列进行处理,所以如果一个文件中的每行都被特定的分隔符(常见的是空格)隔开,我们可以将这个文件看成是由很多列的文本组成,这样的文件最适合用awk进行处理,其实awk在工作中很多时候被用来处理log文件,进行一些统计工作等。

环境描述

文件file1.txt,存储了个人工作信息,这个文件包含名字,工作时间,每小时工资等信息

Jack 10 12

Alice 8 13

Mary 9 20

Susie 11 10

awk程序的结构

awk都是由一个或者多个模式-动作语句组成的序列:

pattern { action }

pattern { action }

1.awk的基本操作是由输入行组成的序列中,陆续的扫描执行每一行,搜索可以被模式匹配的行,每一个输入行轮流被测试一遍,每匹配到一个模式,对应的动作就会执行,然后下一行开始,匹配重新开始,这个过程一直持续到文件被读取完毕为止。通常,模式是可选的,所以动作使用{}括起来,以便区分两者。

2.命令行中的程序被单引号包围时,这个规定可以防止程序中的字符串(例如$)被shell解释,也可以让程序的的长度多于一行。

3.当程序的长度比较短的时候,直接写会比较方便,但是比较长的时候,需要放到文件中,例如文件名为pgfile,这是只要键入

awk –f pgfile

4.模式

模式中可以使用比较符>,>=,==,<,<=,!=,并且还可以使用并且与或者(&&,||)

大于(>=):awk '$2>=10 { print $1 }' file1.txt

大于(>):awk '$2>10 { print $1 }' file1.txt

等于(==):awk '$2==10 { print $1 }' file1.txt

不等于(!=):awk '$2!=10 { print $1 }' file1.txt

小于等于(<=):awk '$2<=10 { print $1 }' file1.txt

小于(<):awk '$2<10 { print $1 }' file1.txt

并且&&:awk '$2=1 && $3<10 { print $1 }' file1.txt (打印的行满足$2>1并且$3<10)

或者||:awk '$2>11 || $3<=10 { print $1 }' file1.txt (打印的行满足:当$2>11或者$3<=10的时候)

特殊说明

1.awk中的$1表示第一个字段,$2表示第二个字段,以此类推,$0表示一整行

2.awk计算当前输入行的字段数量,并记录到一个内置变量NF中,因此程序{print NF}为打印输入行字段数量

3.awk还提供了另外一个变量NR,我们可以使用NR和$0为每一行加上行号{ print $0,NR }

4.单词也可以用于与表达式组合;例如:awk '{ print "Total pay for",$1,"is",$2*$3 }' file1.txt

其它内置函数:

awk定义了很多内置函数,下面我们根据函数类型列出常用的函数,下面的函数只是一部分,完整的函数列表则需要查阅awk的官方文档。

算术:
atan2(y,x) 返回 y/x 的反正切。
cos(x) 返回 x 的余弦;x 是弧度。
sin(x) 返回 x 的正弦;x 是弧度。
exp(x) 返回 x 幂函数。
log(x) 返回 x 的自然对数。
sqrt(x) 返回 x 平方根。
int(x) 返回 x 的截断至整数的值。
rand() 返回任意数字 n,其中 0 <= n < 1。
srand([expr]) 将 rand 函数的种子值设置为 Expr 参数的值,或如果省略 Expr 参数则使用某天的时间。返回先前的种子值。
字符串:
gsub(reg,str1,str2) 使用str1替换所有str2中符合正则表达式reg的子串
sub(reg,str1,str2) 含义与gsub相同,只不过gsub是替换所有匹配,sub只替换第一个匹配
index(str,substr) 返回substr在str中第一次出现的索引,注意索引从1开始计算,如果没有则返回0
length(str) 返回str字符串的长度,length函数还可以返回数组元素的个数
blength(str) 返回字符串的字节数
match(str,reg) 与index函数一样,只不过reg使用正则表达式,例如match("hello",/lo/)
split(str,array,reg)将str分隔成数组保存到array中,分隔使用正则reg,或者字符串都可以,返回数组长度
tolower(str) 转换为小写
toupper(str) 转换为大写
substr(str,start,length) 截取字符串,从start索引开始的length个字符,如不指定length则截取到末尾,索引从1开始
其他:
system(command) 执行系统命令,返回退出码
mktime( YYYY MM dd HH MM ss[ DST]) 生成时间格式
strftime(format,timestamp) 格式化时间输出,将时间戳转换为时间字符串
systime() 得到时间戳,返回从1970年1月1日开始到当前时间(不计闰年)的整秒数

printf输出

print用于简单快速输出,如果想要格式化输出,可以使用printf

格式

printf(format,value1,value2…valueN)

format是一个字符串,包含按字面打印的文本,中间散布着格式说明,格式说明符用于说明如何打印。一个格式说明符是一个%,后面跟着几个字符,这些字符控制着一个value的输出格式。格式说明符的数量应该和打印的value一样多

例如:

awk '{ printf("Total pay for s% is %.2f\n",$1,$2*$3) }' file1.txt

但是printf不会自动产生换行符或空格符,用户必须自己创建。

数据验证

awk还是一款数据验证工具

真是的数据总数存在错误的,检查数据是否有合理的值,格式是否正确,这种任务叫做数据验证。

例如:

awk 'NF != 3 { print $0,"Number of fields is not equal to 3" }' file1.txt

BEGIN与END

特殊的模式BEGIN在第一个输入文件的第一行之前被匹配,END在最后一个输入文件的最后一行被处理之后匹配

Linux:/usr/local/sbin # echo -e '11 12 13\n21 22 23' | awk 'BEGIN{ print "col1 col2 col3";print ""}{ print $2,$1,$3 }'

col1 col2 col3

12 11 13

22 21 23

此命令将echo输出的内容通过管道传输给awk,然后格式化输出,print ""为打印单独的空行。这里echo命令使用了-e选项的目的就是为了保持字符串中的\n的格式能够生效,否则该换行将被忽略。

Linux:/usr/local/sbin # echo -e "1 2 3" | awk 'BEGIN{ print "begin" }{ print $1 }END{ print "end" }'

begin

1

end

awk计算

1.这个程序用于计算工作时间大于等于10h的员工数

Linux:/usr/local/sbin # awk '$2>=10 { cnt=cnt+1 }END{ print cnt,"employees worked more than 10h"}' file1.txt

2 employees worked more than 10h

此处的cnt为自定义的变量,cnt=cnt+1的意思为:每次读取一行,如果满足则依次加1.

2.计算员工的总报酬与平均报酬

Linux:/usr/local/sbin # awk '{ pay=pay+$2*$3 }END{ print "Total pay is ",pay ;print "Average pay is ",pay/NR }' file1.txt

Total pay is  514

Average pay is  128.5

当NR值为0的时候,则程序会报错提示除数不为0

3.求出工作时间最长的

Linux:/usr/local/sbin # awk '$2>maxtime {maxtime=$2;maxname=$1}END{ print maxtime,maxname }' file1.txt

11 Susie

变量maxtime保存的是数值,maxname保存的是字符串;

4.拼接字符串

Linux:/usr/local/sbin # awk '{ names=names $1 "@|@"}END{ print names}' file1.txt

Jack@|@Alice@|@Mary@|@Susie@|@

此命令是将员工名字以@|@的方式进行拼接,names为初始自定义变量。

流程控制语句

if-else语句

Linux:/usr/local/sbin # echo -e '23 man Jack' | awk '{if($1<18) print "The boy is underage"; else print "The boy has group up"; }'

The boy has group up

根据孩子的年龄来判断该孩子是否成年,成年则打印The boy has group up否则打印 The boy is underage(该孩子未成年)

while语句

while含有条件判断和循环体,如果条件为真的话,循环体执行。

Linux:/usr/local/sbin # awk 'BEGIN{ count=1;while(count<=6){ print count;count ++}}'

1

2

3

4

5

6

count初始赋值为1,依次加1,当count超过6,则停止循环;

for语句

Linux:/usr/local/sbin # awk 'BEGIN{ for(i=1;i<=5;i++) print i }'

1

2

3

4

5

常用命令行

awk 'END{print NR}' file1.txt  #输入总行数

awk 'NR==2' file1.txt            #打印第二行

awk '{print $NF}' file1.txt    #打印最后一列

awk 'NF>2' file1.txt           #打印字段数多于2个的行

awk '$NF>12' file1.txt         #打印字段数多于2个的行

awk '{nf=nf+NF}END{ print nf }' file1.txt  #打印输出的字段总个数

awk '/Su/{ line=line+1 }END{ print line}' file1.txt  #打印包含字符Su的行的数量

awk '$2>maxnum {maxnum=$2;maxname=$1}END{ print maxnum,maxname}' file1.txt  #打印$2最大值

awk 'NR>0' file1.txt  #打印至少包含一个字段的行

awk 'length($0)>10' file1.txt  #打印长度超过10的行

awk '{ print NF,$0 }' file1.txt #每一行前添加字段数

awk '{ print $3,$2,$1 }' file1.txt #打印每一行的字段,但是顺序相反

awk '{ $1=NR;print }' file1.txt #每一行的第一个字段用行号替换并打印

awk '{ $2="";print }' file1.txt #打印除第二行外的其他行

案例描述

1.现在想求出每个人的当天的报酬信息(并且每个人的工作时间必须大于0)

Linux:/usr/local/sbin # awk '$2>0 {print $1,$2*$3}' file1.txt

Jack 120

Alice 104

Mary 180

Susie 110

该命令行告诉系统运行awk程序,被运行的程序用单引号包围起来,从file1.txt中获取数据,被单引号包围的是一个完整的awk程序,它由一个独立的模式-动作组成。模式$2 > 0扫描每一个输入行,如果该行的第二列大于0,则执行动作{print $1,$2*$3},此时就会为每一行匹配打印第一个字段,以及第二个字段与第三个字段的乘积,如果想知道工作时间为0的是谁,直接使用awk '$2==0 {print $1}' file1.txt即可打印出来。

2.使用printf打印每位员工的名字与报酬

Linux:/usr/local/sbin # awk '{ printf("%-8s $%6.2f\n",$1,$2*$3) }' file1.txt

Jack     $120.00

Alice    $104.00

Mary     $180.00

Susie    $110.00

第一个格式说明符%-8s,将名字左对齐输出,占用8个字符宽度;第二个格式说明符%6.2f,将报酬以美元并精确小数点2位,占用6个字符长度的方式打印出来。

3.打印出报酬,并升序排序

Linux:/usr/local/sbin # awk '{ printf("%6.2f %s\n",$2*$3,$0)}' file1.txt | sort -n

104.00 Alice 8 13

110.00 Susie 11 10

120.00 Jack 10 12

180.00 Mary 9 20

awk的输出通过管道传输给sort,排序后输出,-n是升序排序,如果需要降序排序,使用-r即可。

4.打印文件的最后一行

Linux:/usr/local/sbin # awk '{ last=$0 }END{ print last }' file1.txt

Susie 11 10

【Linux】awk详细介绍的更多相关文章

  1. Linux 目录详细介绍

    [常见目录说明] 目录 /bin 存放二进制可执行文件(ls,cat,mkdir等),常用命令一般都在这里. /etc 存放系统管理和配置文件 /home 存放所有用户文件的根目录,是用户主目录的基点 ...

  2. linux目录详细介绍

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://yangrong.blog.51cto.com/6945369/1288072 目 ...

  3. Linux Systemd 详细介绍: Unit、Unit File、Systemctl、Target

    Systemd 简介 CentOS 7 使用 Systemd 替换了SysV Ubuntu 从 15.04 开始使用 Systemd Systemd 是 Linux 系统工具,用来启动守护进程,已成为 ...

  4. linux文件目录详细介绍

    linux文件目录 目录 /bin 存放二进制可执行文件(ls,cat,mkdir等),常用命令一般都在这里 /etc 存放系统管理和配置文件 /home 存放所有用户文件的根目录,是用户主目录的基点 ...

  5. linux 防火墙详细介绍

    1.其实匹配扩展中,还有需要加-m引用模块的显示扩展,默认是隐含扩展,不要使用 -m状态检测的包过滤-m state       --state {NEW,ESTATBLISHED,INVALID,R ...

  6. linux awk 内置函数详细介绍(实例)

    这节详细介绍awk内置函数,主要分以下3种类似:算数函数.字符串函数.其它一般函数.时间函数 一.算术函数: 以下算术函数执行与 C 语言中名称相同的子例程相同的操作: 函数名 说明 atan2( y ...

  7. linux awk 内置函数详细介绍(实例)

    这节详细介绍awk内置函数,主要分以下3种类似:算数函数.字符串函数.其它一般函数.时间函数 一.算术函数: 以下算术函数执行与 C 语言中名称相同的子例程相同的操作: 函数名 说明 atan2( y ...

  8. linux shell awk 流程控制语句(if,for,while,do)详细介绍

    在linux awk的 while.do-while和for语句中允许使用break,continue语句来控制流程走向,也允许使用exit这样的语句来退出.break中断当前正在执行的循环并跳到循环 ...

  9. awk 正则表达式、正则运算符详细介绍

    前言:使用awk作为文本处理工具,正则表达式是少不了的. 要掌握这个工具的正则表达式使用.其实,我们不必单独去学习它的正则表达式.正则表达式就像一门程序语言,有自己语法规则已经表示意思. 对于不同工具 ...

随机推荐

  1. [Web 前端] React Router v4 入坑指南

    cp from : https://www.jianshu.com/p/6a45e2dfc9d9 万恶的根源 距离React Router v4 正式发布也已经过去三个月了,这周把一个React的架子 ...

  2. [PHP] 6种负载均衡算法

    CP from  : https://www.cnblogs.com/SmartLee/p/5161415.html http://www.dataguru.cn/thread-559329-1-1. ...

  3. Java中的Future模式原理自定义实现

    摘要:Future模式类似于js中的ajax等,是一个异步获取数据的机制,这里我把自己的一些形象理解通过代码实现了一下.该机制可以形象的理解为:调用获取数据的方法,首先获得一个没有装数据的空箱子(这个 ...

  4. [转]MySQL事务学习-->隔离级别

    From : http://blog.csdn.net/mchdba/article/details/12837427 6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性 ...

  5. Kafka学习入门

    最近工作中用到了两个很给力的项目,一个是Kafka,一个是Strom.本着自我学习并方便他人的目的,我会将我觉得比较有用的英文文档翻译在此(保留系统专有名词不作翻译). 1kafka介绍 在流式计算中 ...

  6. go语言之进阶篇runtime包中 Gosched Goexit GOMAXPROCS的使用

    一.runtime包 1.Gosched的使用 runtime.Gosched() 用于让出CPU时间片,让出当前goroutine的执行权限,调度器安排其他等待的任务运行,并在下次某个时候从该位置恢 ...

  7. [leetcode]Merge Intervals @ Python

    原题地址:https://oj.leetcode.com/problems/merge-intervals/ 题意: Given a collection of intervals, merge al ...

  8. android bundle 对象 序列化

    Android使用Intent.putSerializable()进行数据传递,或者使用Bundle进行数据传递,实质上都是进行的Serializable数据的操作,说白了都是传递的原数据的一份拷贝, ...

  9. Python 中parse.quote类似JavaScript encodeURI() 函数

    from urllib import parse jsRet = 'roleO%2f'print(parse.unquote(jsRet))print(parse.quote(jsRet))输出: r ...

  10. JAVA-SpringMVC基于注解模式第一个应用

    项目文件结构 1. web.xml配置文件 <?xml version="1.0" encoding="UTF-8"?> <web-app x ...