1、awk的概述

文本处理工具,由于功能的强大,也可以当做是一种数据操作语言,非常适合结构化数据的处理和格式化报表的生成,awk可以进行样式装入、流控制、数学运算符、甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。

为什么叫awk?

三个人(Alfred Aho、 Peter Weinberger 、Brian Kernighan。)一起创造了这款工具,awk分别是他们名字的缩写

从网上找到以下数据提供练习:包含名字,电话号码和过去三个月(1月份、2月份、3月份)里的捐款,文件名称命名为data.txt

Mike Harrington:[510] 548-1278:250:100:175

Christian Dobbins:[408] 538-2358:155:90:201

Susan Dalsass:[206] 654-6279:250:60:50

Archie McNichol:[206] 548-1348:250:100:175

Jody Savage:[206] 548-1278:15:188:150

Guy Quigley:[916] 343-6410:250:100:175

Dan Savage:[406] 298-7744:450:300:275

Nancy McNeil:[206] 548-1278:250:80:75

John Goldenrod:[916] 348-4278:250:100:175

Chet Main:[510] 548-5258:50:95:135

1.1、一些名词定义

  • 数据行(Record) : awk从数据文件上读取数据的基本单位,一次读取一行数据
  • 字段(Field) : 数据行上被分隔开的子字符串

1.2、内置变量

变量 描述
$0 一字符串, 其内容为目前 awk 所读入的数据行
$n $1为$0上第一个字段的数据,$2为$0 上第二个字段的数据
ARGC 命令行参数的数目
ARGIND 命令行中当前文件的位置(从0开始算)
ARGV 包含命令行参数的数组
CONVFMT 数字转换格式(默认值为%.6g)
ENVIRON 环境变量关联数组
ERRNO 最后一个系统错误的描述
FIELDWIDTHS

字段宽度列表(用空格键分隔)

FILENAME 当前文件名
FNR 同NR,但相对于当前文件
FS 字段分隔符(默认是任何空格)
IGNORECASE 如果为真,则进行忽略大小写的匹配
NF 当前记录中的字段数
NR 当前记录数
OFMT 数字的输出格式(默认值是%.6g)
OFS 输出字段分隔符(默认值是一个空格)
ORS 输出记录分隔符(默认值是一个换行符)
RLENGTH 由match函数所匹配的字符串的长度
RS 记录分隔符(默认是一个换行符)
RSTART 由match函数所匹配的字符串的第一个位置
SUBSEP 数组下标分隔符(默认值是\034)

2、AWK语法

基本语法:awk -[vFf] Pattern { Action }

-[vFf]为参数;Pattern 为模式;Action 为操作

2.1、awk工作流程

  • 自动从指定的数据文件中读取一个数据行.
  • 自动更新(Update)相关的内建变量之值. 如 : NF, NR, $0...
  • 依次执行程序中 所有 的 Pattern { Actions } 指令.
  • 当执行完程序中所有 Pattern { Actions } 时, 若数据文件中还有未读取的数据, 则反复执行步骤1到步骤3

两者是可选的,如果没有模式,则action应用到全部记录,如果没有action,则输出匹配全部记录。默认情况下,每一个输入行都是一条记录,但用户可通过RS变量指定不同的分隔符进行分隔。

2.2、参数

  • -v  定义变量,例如:awk -v a=test '{print a}' data.txt

如果有两个变量,在后面再加多一个-v参数再赋予一个变量值

  • -F 分隔符 awk -F: '{print $1}' data.txt
  • -f 指定awk脚本

2.3、模式

  • 关系表达式 :使用像 " A 关系运算符 B" 的表达式当成 Pattern
运算符 描述
= += -= *= /= %= ^= **= 赋值,注:=是赋值,==是判断符,即关系运算符
?: C条件表达式
|| 逻辑或
&& 逻辑与
~ ~! 匹配正则表达式和不匹配正则表达式
< <= > >= != == 关系运算符
空格 连接
+ - 加减
* / & 乘除与求余
+ - ! 一元加减和逻辑非
^ *** 求幂
++ -- 增加或减少,作为前缀或后缀
$ 字段引用
in 数组成员
  • 正则表达式 : 在两个斜杠中(//)使用正则表达式
  • 模式的组合
  • BEGIN 和 END 模式

2.4、操作

操作由一人或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。主要有四部份:

  • 变量或数组赋值
  • 输出命令:print或者printf命令
  • 内置函数
  • 控制流命令

3、正则表达式

在两个斜杠中(//)使用正则表达式

写法如下:

awk -F: '$1 ~/^Mike/{print $0}' data.txt

4、模式的组合

模式:指定一个行的范围。

/begin/,/end/

包含字符串 begin (第一次出现)的数据行以及和包含字符串 end (第一次出现)之间的所有记录(包含包括字符串 end 的记录)匹配。

例如:打印出Mike和Dan之间的的信息

awk -F:  '/^Mike/,/^Dan/{print NR,$0}' data.txt

5、BEGIN和END模式

5.1 BEGIN

BEGIN模块后紧跟着动作块,这个动作块在awk处理任何输入文件之前执行。所以它可以在没有任何输入的情况下进行测试。它通常用来改变内建变量的值,如OFS,RS和FS等,以及打印标题

例如:输出每个人第一个月的捐款,冒号分隔符

awk 'BEGIN{FS=":"}{print $1":"$3}' data.txt

这里使用BEGIN在处理这个字符之前改变内建变量FS,如果要改变多个内置变量,使用”;”分隔符

例如:输出每个人第一个月的捐款,冒号分隔符,

awk 'BEGIN{FS=":";OFS=":"}{print $1":"$3}' data.txt

FS:字段分隔符(默认空格)

OFS:输出字段分隔符(默认空格)

5.2 END

END不匹配任何的输入文件,但是执行动作块中的所有动作,它在整个输入文件处理完成后被执行。

重点理解在”在整个输入文件处理完成后被执行“这句话,也即是在处理完后才处理动作快中的动作,没有加这个END的时候,在处理完每一条记录,都会执行action中的动作,加了END后,只有处理完后才执行action中的动作。

做个对比:

awk -F":" '{print "number is:"NR}' data.txt

awk -F":" 'END{print "number is:"NR}' data.txt

执行完最后一行才输出,此时NR变量是10

6、条件语句(控制流命令)

6.1 if语句

语法:

{if (expression){

statement; statement; ...

}

}

例如:

awk '{if(100>50){print "A>B"}}' data.txt

6.2 if/else语句

{if (expression){

statement; statement; ...

}

else{

statement; statement; ...

}

}

例如:

awk '{if(100>150){print "A>B"}else{print "B<A"}}' data.txt

6.3 if/else else if语句

{if (expression){

statement; statement; ...

}

else if (expression){

statement; statement; ...

}

else if (expression){

statement; statement; ...

}

else {

statement; statement; ...

}

}

6.4 while循环

例如,输出第一行每个字段的值

awk 'NR==1{print $0}' data.txt |awk -F: '{i=1;while(i<=NF){print i,$i;i++}}'


6.5 for循环

例如,输出第一行每个字段的值

awk 'NR==1{print $0}' data.txt |awk -F: '{for(i=1;i<=NF;i++){print i,$i}}'

break与continue语句

break用于在满足条件的情况下跳出循环;continue用于在满足条件的情况下忽略后面的action语句,继续往下循环

测试数据源data2.txt:

100 200 -100 300 -200

例如:只输出第一个负数值

awk '{for(i=1;i<=NF;i++)if($i<0){print $i;break}}' data2.txt

7、printf函数

printf是一个格式化的函数,使得输出的格式更美观、整齐,先来看一个用法

awk -F[:] '{printf("%-19s,%-20s,%-5d,%-5d,%-5d\n",$1,$2,$3,$4,$5)}' data.txt

语法如下:

printf("格式化字符串",参量表 )

参量表是需要输出的一系列参数, 其个数必须与格式化字符串所说明的输出参数个数一样多, 各参数之间用","分开, 且顺序一一对应, 否则将会出现意想不到的错误。

例如上面:awk -F[:] '{printf("%-19s,%-20s,%-5d,%-5d,%-5d\n",$1,$2,$3,$4,$5)}' data.txt

这里对5个字段做了格式化,参量表就必须有5个参数,就是这里的$1,$2,$3,$4,$5

格式化字符串又分为如下的修饰符和格式说明符

7.1 修饰符

字符 定义
- 左对齐修饰符,常用
#

显示8 进制整数时在前面加个0
显示16 进制整数时在前面加0x

+ 显示使用d 、e 、f 和g 转换的整数时,加上正负号+或-
0 用0而不是空白符来填充所显示的值

7.2 格式说明符

格式说明符 功能
%d 十进制有符号整数
%u 十进制无符号整数
%f 浮点数
%s 字符串
%c 单个字符
%p 指针的值
%e 指数形式的浮点数
%x %X 无符号以十六进制表示的整数
%0 无符号以八进制表示的整数
%g 自动选择合适的表示法
\n 换行
\f 清屏并换页
\r 回车
\t Tab符
\xhh 表示一个ASCII码用16进表示,其中hh是1到2个16进制数

说明:

(1). 可以在"%"和字母之间插进数字表示最大场宽。

例如:

  • %3d 表示输出3位整型数, 不够3位右对齐。
  • %9.2f 表示输出场宽为9的浮点数, 其中小数位为2, 整数位为6,小数点占一位, 不够9位右对齐。
  • %8s 表示输出8个字符的字符串, 不够8个字符右对齐。

如果字符串的长度、或整型数位数超过说明的场宽, 将按其实际长度输出.但对浮点数, 若整数部分位数超过了说明的整数位宽度, 将按实际整数位输出;若小数部分位数超过了说明的小数位宽度, 则按说明的宽度以四舍五入输出.

(2).另外, 若想在输出值前加一些0, 就应在场宽项前加个0。

例如: %04d 表示在输出一个小于4位的数值时, 将在前面补0使其总宽度为4位。

如果用浮点数表示字符或整型量的输出格式, 小数点后的数字代表最大宽度,小数点前的数字代表最小宽度。

例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。

(3). 可以在"%"和字母之间加小写字母l, 表示输出的是长型数。

例如: %ld 表示输出long整数

%lf 表示输出double浮点数

(4). 可以控制输出左对齐或右对齐, 即在"%"和字母之间加入一个"-" 号可说明输出为左对齐, 否则为右对齐。

例如: %-7d 表示输出7位整数左对齐

%-10s 表示输出10个字符左对齐

8、数组

用变量作为数组下标,数组name中的下标是一个自定义变量x,awk初始化x的值为0,在每次使用后增加1。第二个域的值被赋给name数组的各个元素。在END模块中,for循环被用于循环整个数组,从下标为0的元素开始,打印那些存储在数组中的值。因为下标是关健字,所以它不一定从0开始,可以从任何值开始。

awk 'BEGIN{FS=":"}{name[x++]=$1}END{for(i=0;i<NR;i++)print i,name[i]}' data.txt

把$1的值分别赋给name[0],name[1],name[2]·········

上面每行一次输出的是name[0],name[1]····

延伸:这里x的初始值是0,可以更改这个初始值吗,可以的,如下,设置x的初始值为2

awk 'BEGIN{FS=":";x=2}{name[x++]=$1":"$3}END{print name[2]}' data.txt

8.1 关于数组的几道题

数据data1.txt:第一个字段为姓名,第二、三、四字段为课程

xiaoming Chinese English Mathematics

xiaoli English Mathematics

xiaohua Chinese Mathematics

xiaohong English

题目:求出参加Chinese English Mathematics课程的修课人数

awk '{for(i=2;i<=NF;i++)num[$i]++}END{for(course in num)printf("%-10s %d\n",course,num[course])}' data1.txt


9、内置函数

9.1 sub(reg,string,target)

将原字串中第一个(最左边)合乎所指定的正则表达式的子字串改以新字串取代. 第二个参数"将替換的新字串"中可用"&"来代表"合於条件的子字串"

例如:把Dan字符替换成aaaaa字符

awk '{sub(/Dan/,"aaaaa",$0);print $0}' data.txt

9.2 gsub(reg,string,target)

这个函数与 sub()一样,同样是进行字串取代的函数. 唯一不同点 gsub()会取代所有合条件的子字串. gsub()会返回被取代的子字串个数

9.3 length(string)

返回该字串的长度

例如:

awk -F: '{print length($1)}' data.txt

9.4 substr函数

返回从位置1开始的子字符串,如果指定长度超过实际长度,就返回整个字符串。格式如下

返回字段1的第一个字符到第三个字符,如果超过字段1的实际长度,返回整个字段1

awk -F: '{ print substr( $1, 1,3 )}' data.txt

9.5 toupper和tolower函数

toupper和tolower函数可用于字符串大小间的转换,该功能只在gawk中有效

awk -F: '{ print toupper($1), tolower($1) }' data.txt

9.6 split(string,store,delim)

awk将依所指定的分隔字符(field separator)来分隔原字串成一个个的栏位(field),并以指定的数组(下标从1开始)记录各个被分隔的栏位.

例如:以:号为分隔符,对$2进行分割,并存到name[]数组中

awk -F: '{split($2,name," "); print name[1] }' data.txt

10、awk练习题

10.1 复习

  1. 输出文本,在文本前面输出文本所在的数据行
  2. 打印Mike和Dan的电话号码
  3. 打印出文本中Dan往下全部人的信息
  4. 显示Mike的捐款,每个值前面加上$符号
  5. 分别显示每个人这个季度捐款总额
  6. 显示全部人的捐款总额
  7. 统计某个文件夹下的文件占用的字节数

参考答案:

  1. awk '{print NR,$0}' data.txt
  2. awk -F: '$1 ~/^Mike/||$1 ~/^Dan/{print NR,$0}' data.txt
  3. awk 'BEGIN{a=1000000000000}{if($1 ~/^Dan/){a=NR;print NR,$0}else if(NR>=a){print NR,$0}}' data.txt
  4. awk -F: '$1 ~/^Mike/{print $1,"$"$3,"$"$4,$5}' data.txt
  5. awk -F: 'sum=$3+$4+5{print $1,sum}' data.txt
  6. awk -F: 'sum=$3+$4+$5{total=total+sum}END{print total}' data.txt
  7. ls -al |awk '$1 ~/^-/{total=total+$5}END{print total}'

10.2 打印出使用率大于60的文件系统

文本数据:

Filesystem             Size   Used  Available Capacity  Mounted on

rpool/ROOT/solaris-1   274G    14G        18G    44%    /

swap                    44G   1.1M        44G     1%    /tmp

rpool/VARSHARE         274G    93M        18G     1%    /var/share

backup                 274G   200G        74G    73%    /backup

rpool/export           274G  1004M        18G     6%    /export

rpool/export/home      274G    75K        18G     1%    /export/home

rpool/export/home/dninms
                        274G   2.7G        18G    14%    /export/home/dninms

rpool/export/home/doc
                        274G   166M        18G     1%    /export/home/doc

rpool/export/home/fms
                        274G    93G        18G    84%    /export/home/fms

rpool/export/home/nsm-aaa
                        274G   742M        18G     4%    /export/home/nsm-aaa

10.3 制作一张报表

  1. 制作报表:显示每个人1、2、3月份的捐款
  2. 在第一行加上报头

参考答案:

  1. awk -F: '{printf("%-20s 1月份捐款:%-5d 2月份捐款:%-5d 3月份捐款:%-5d\n"),$1,$3,$4,$5}' data.txt
  2. awk 'BEGIN{FS=":";printf("%-20s %-10s %-10s %-5s\n"),"姓名","1月份捐款","2月份捐款","3月份捐款"}{printf("%-20s %-10d %-10d %-5d\n"),$1,$3,$4,$5}' data.txt

AWK编程的更多相关文章

  1. 第4章 awk编程

    1 awk编程模型       2 awk用法 调用awk有三种方法(与sed类似): 在Shell命令行输入命令调用awk,格式为: awk [-F 域分隔符] 'awk程序段' 输入文件 将awk ...

  2. shell编程练习-打印九九乘法表(附:awk编程)

    小练习,仅供参考 shell编写 #!/bin/bash for i in {1..9}do for j in {1..9} do if [ $j -le $i ] ;then echo -ne &q ...

  3. awk编程基础

    一.awk介绍 awk(名字来源于三个创始人姓氏首字母)是linux系统下文本编辑工具,是一门编程语言,有自己的基本语法和流程控制.函数.awk简单高效.   二.awk的运行方法 例子:使用冒号:分 ...

  4. awk编程的基本用法

    awk也是用来处理文本的,awk语言可以从文件或字符串中基于指定规则浏览和抽取信息,可以实现数据查找.抽取文件中的数据.创建管道流命令等功能. awk模式匹配 第一种方法打印空白行将空白行打印出来,并 ...

  5. 『忘了再学』Shell基础 — 27、AWK编程的介绍和基本使用

    目录 1.AWK介绍 (1)AWK概述 (2)printf格式化输出 (3)printf命令说明 2.AWK的基本使用 (1)AWK命令说明 (2)AWK命令使用 1.AWK介绍 (1)AWK概述 A ...

  6. Linux Shell编程第4章——sed和awk

    目录 sed命令基本用法 sed命令实例 命令选项 文本定位 编辑命令 awk编程模型 awk编程实例 1.awk模式匹配 2.记录和域 3.关系和布尔运算符 4.表达式 5.系统变量 6.格式化输出 ...

  7. Linux Shell编程 awk命令

    概述 awk是一种编程语言,用于在linux/unix下对文本和数据进行处理.数据可以来自标准输入(stdin).一个或多个文件,或其它命令的输出.它支持用户自定义函数和动态正则表达式等先进功能,是l ...

  8. awk命令简介

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

  9. 【Linux】AWK入门

    什么是AWK AWK是一种用于处理文本的编程语言工具,一个模式匹配程序.一个典型的示例是将数据转换成格式化的报告. 在命令行输入如下awk命令: awk -F":" '{ prin ...

随机推荐

  1. 【OCR技术系列之六】文本检测CTPN的代码实现

    这几天一直在用Pytorch来复现文本检测领域的CTPN论文,本文章将从数据处理.训练标签生成.神经网络搭建.损失函数设计.训练主过程编写等这几个方面来一步一步复现CTPN.CTPN算法理论可以参考这 ...

  2. 【WPF】ImageMagick调节图片的颜色

    需求:打开一张图片后,自由调节图片的颜色(色调). 思路:读取显示一张图片后,用ColorPicker取色器选择一种颜色,之后将图片的色调调节为该颜色. 工具: 1.图像工具 ImageMagick( ...

  3. [Java并发编程(三)] Java volatile 关键字介绍

    [Java并发编程(三)] Java volatile 关键字介绍 摘要 Java volatile 关键字是用来标记 Java 变量,并表示变量 "存储于主内存中" .更准确的说 ...

  4. go语言关键字图示

    Go语言一共有25个关键字,除了select,上文基本上已经一网打尽了.为了加深印象,我们用一张结构图来说明一下: 这张图如果看不清的话,我们将其拆成两张图,再注掉分支流程那部分的局部图: 分支流程部 ...

  5. DirectX using C++_error X3539:ps1_x is no longer supported...解决方案

    问题来源 在研究HLSL时编译一个demo出现了error X3539的问题 解决方案 将代码中的ps_1_1 改为ps_2_0 PixelShader = compile ps_1_1 PS(); ...

  6. docker进程分析

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/TM6zNf87MDG7Bo/article/details/80970541 序言      闷热. ...

  7. 使用winsw部署spring boot jar 项目

    参考:用winsw让任何Windows程序都能运行为服务 简介在linux下部署springboot项目是一件很简单的事,直接后台运行就行了,最多写个shell脚本开机自启就行了.我们最近做的项目需要 ...

  8. easyui的tree节点的获取和选中

    1.设置选中tree的节点 var node = $('#tt').tree('find', 1);//找到id为”tt“这个树的节点id为”1“的对象$('#tt').tree('select', ...

  9. 1开放封闭原则OCP

    一.什么是开放封闭原则 开放封闭原则(Open-Closed Principle):一个软件实体 应当对扩展开放,则修改关闭. 在设计一个模块时,应当使得这个模块可以在不被修 改的前提下被扩展.也就是 ...

  10. ganglia-gmond.conf配置文件

    运行下列命令可以生成gmond默认配置文件: User@host:$ gmond -t 配置文件由大括弧括起来的几个section组成.这些section可以粗略划分为两个逻辑分类.第一类中的sect ...