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. Emulator: glTexImage2D: got err pre :( 0x502 internal 0x1908 format 0x1908 type 0x1401

    Go to Tools > AVD Manager > Virtual device configuration > Show advanced settings > Boot ...

  2. npm出错的解决方案

    npm show grpc # 返回版本号 # 安装旧版本: npm install grpc@1.2.0

  3. ARCH模型

    ARCH模型的基本思想 ARCH模型的基本思想是指在以前信息集下,某一时刻一个噪声的发生是服从正态分布.该正态分布的均值为零,方差是一个随时间变化的量(即为条件异方差).并且这个随时间变化的方差是过去 ...

  4. Html、Asp、Php、Jsp禁止页面缓存

    html:<meta http-equiv="pragma" content="no-cache"><meta http-equiv=&quo ...

  5. SpringBoot 使用Swagger2打造在线接口文档(附汉化教程)

    原文地址: https://www.jianshu.com/p/7e543f0f0bd8 SpringBoot + Swagger2 UI界面-汉化教程 1.默认的英文界面UI 想必很多小伙伴都曾经使 ...

  6. 7.3 netty3基本使用

    由于dubbo默认使用的是netty3进行通信的,这里简单的列出一个netty3通信的例子. 一 server端 1 Server package com.hulk.netty.server; imp ...

  7. Remove Duplicates from Sorted Array II leetcode java

    题目: Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For e ...

  8. Populating Next Right Pointers in Each Node II leetcode java

    题目: Follow up for problem "Populating Next Right Pointers in Each Node". What if the given ...

  9. 混合开发 Hybird Cordova PhoneGap web 跨平台 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  10. 【Javascript设计模式1】-单例模式

    <parctical common lisp>的作者曾说,如果你需要一种模式,那一定是哪里出了问题.他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案. 不管是弱类型 ...