awk学习笔记

awk是一种模式扫描和处理工具,相对于grep的查找,sed的编辑,它在对数据进行分析生成报表时显得尤为强大。awk通过逐行遍历一个或多个 文件的方式,查找模式匹配到的行,而后以指定的分隔符(缺省为空格)进行切片,然后针对切片数据进行处理和分析。事实上,gawk有自己的语言,其本身就 相当于一个解释器,允许用户创建简短的程序读取输入文件,对输入数据执行排序、计算以及生成报表操作,甚至可以类似bash shell实现诸如循环、数组、条件判断、函数、变量等功能,进而完成更为复杂的数据分析处理任务。

Gawk

gawk(GNU awk)是UNIX awk的GNU版,为方便linux用户使用,通常将/bin/awk以符号链接方式链接到/bin/gawk,以迎合用户的使用习惯。(下文有提到gawk的地方均以awk代替)

awk的使用方式

1、命令行方式

awk [-F field-separator] ‘COMMAND’inputfiles

//其中COMMAND是awk的执行命令,用来处理数据,[-F field-separator]是可选选项,inputfiles是待处理文件。

//awk使用中,需要处理的文件,逐行使用分隔符分割成若干个字段,称之为域,分隔符默认是空格,可使用-F选项来指定分隔符

2、shell脚本模式

将所需执行的awk命令插入awk脚本文件,然后在首行设置命令解释器为#!/bin/awk,通过键入脚本名的方式调用。

3、所有awk命令写入到一个单独的文件,当处理同一类文件需求时,使用awk -f awk-script inputfiles调用之,其中awk-script指awk脚本。

awk的基本语法

awk [OPTION] 'program' FILE1 FILE2…

program:PATTERN{ACTION STATEMENT} //program由语句组成,各语句之间使用;隔开,整个program要用单引号引起来

OPTION:选项

-F:指定分割符

例,指定分隔符为“:”,打印出系统上各用户名和morenshell

# awk -F: '{print $1,$7}' /etc/passwd

-v:指定变量

例,通过-v选项指定变量a=hello awk 然后将其打印出来

# awk -v a="hello awk" '{print a}'

另外,也可以通过特殊模式BEGIN(模式下述)来指定变量,如上例,也可以这样写

# awk 'BEGIN{a="hello awk"}{print a}'

-f:指定脚本文件

awk变量

awk的变量,可分类为内置变量和自定义变量

1、内置变量

2、自定义变量

自定义变量有两种方式(上文基本语法中已有示例,此处不再赘述),但是,在脚本中仍然可以声明变量。

(1)、awk -v VARIABLE_NAME VARIABLE_VALUE 'program' inputfiles

(2)、awk 'BEGIN{VARIABLE_NAME VARIABLE_VALUE}ACTION STATEMENT}' inputfiles

3、变量使用示例

(1)、FS输入分隔符,默认为空格

例如,默认分隔符使用awk提取/etc/inittab中的“#”,如下图可以看到,如果以空格分割,第一个域即为#(忽略最后一行)

# awk '{print $1}' /etc/inittab //效果如下(最后一行请忽略)

以“:”为分隔符,提取系统中用户名以及用户默认

# awk -v FS=":" '{print $1,$7}' /etc/passwd

(2)、输出分隔符,默认为空格(如上图上例显示结果),接上例,以:为输出分隔符显示输出结果

# awk -v FS=":" -v OFS=":" '{print $1,$7}' /etc/passwd

(3)、NR和FNR

显示/etc/{inittab,passwd}所有内容以及行数

# awk '{print NR,$0}' /etc/{inittab,passwd}//看下图,行数不分开计数

# awk '{print FNR,$0}' /etc/{inittab,passwd}//看下图,使用FNR单独计数行数

# awk 'BEGIN{print "filename","alone_lines","unit_lines"}{print FILENAME,NR,FNR}' /etc/{passwd,inittab,group}//还可以这样写来分别显示总行号和单独行号,此处不再贴图

(4)、ARGC显示参数个数

# awk -F: '{print $1}END{print ARGC}' /etc/passwd //如下图,显示参数为二(经验证,貌似program也被识别成为一个参数,再加上后面的文件故为2个参数?)

awk的模式

1、Regular Expression 正则表达式

如其名,使用正则表达式匹配模式,在需要注意的是,在awk中使用正则表达式,匹配字符串要使用双斜线括起来,而后匹配到的行将被切片并分析处理,反之将略过。

取出/etc/passwd中包含root的行并打印出用户名和默认shell

# awk -F: ‘/root/ {print $1,$7}' /etc/passwd

2、Expression 表达式,当表达式的值为真(非零或非空)的行被匹配,仅处理匹配到的行

# awk -F: '$3>=500{print $1,$2,$3}' /etc/passwd

在此列出awk的常用操作符

如果模式自身是=,要写为/=/

条件表达式:

selector?if-true-express:if-false-express 只能是表达式不能使语句

条件表达式中,“:”两侧仅允许使用表达式而不能使用语句

# awk -F: '$3>=500?utype="common user":utype="admin or system user"{print $1 "is" utype} /etc/passwd

3、range行范围,有两种方式来定义此范围

(1)、pattern1,pattern2

从匹配到pattern1的行开始到匹配到pattern2的行为知,此范围的行被awk action处理

# awk 'NR==1,NR==10{print $1,$3,$7} /etc/passwd

4、特殊模式BEGIN和END

(1)、BEGIN在读取任何输入之前执行一次语句

# awk 'BEGIN{FS=":";OFS=":"}/root/{print $1,$3,$7} /etc/passwd

(2)、END在读取所有输入之后执行一次语句

# awk 'BEGIN{FS=":";OFS=":"}/root/{print $1,$3,$7}END{print "The end!"}' /etc/passwd

5、空模式

如果不指定模式则匹配文件中的所有行

awk重定向

1、输出重定向

awk可以使用shell的重定向符重定向输出,同样>代表覆盖式输出,>>代表追加。

覆盖式重定向

追加重定向效果

2、输入重定向

输入重定向需用到getline函数。getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。它负责从输入获得下一行的内 容,并给NF,NR和FNR等内建变量赋值。如果得到一条记录,getline函数返回1,如果到达文件的末尾就返回0,如果出现错误,例如打开文件失 败,就返回-1,可以结合到while等流控制语句使用。

通过例子说明输入重定向用法

(1)、awk 'BEGIN{"date" | getline d; print d}'

getling函数读取date命令的输出结果并将其赋值给自定义变量d,然后打印变量d

(2)、awk 'BEGIN{"date" | getline d; split(d,mon); print mon[3]}'

getine函数读取date命令输出的结果并赋值给自定义变量d,split函数将变量d转化为数组mon,然后打印数组mon的第三个元素。

(3)、awk 'BEGIN{while("ls" | getline) print}'

getline函数读取ls命令的输出结果而后打印显示

awk之print和printf

1、print

用法:print item1,item2….

要点:

(1)、各item之间使用,号隔开,输出时默认以空格分隔

(2)、输出的item可以是字符串或数值、当前分隔出来的域(字段,如$1)、变量或awk的表达式,数值会隐式转换为字符串输出。

(3)、print后面的item项可以省略,此时相当于打印$0即整行内容;print ""表示打印空白行。

例:

# awk 'BEGIN{print "line1","line2","line3"}'

# awk -F: '{print $1,$3,$7}' /etc/passwd

2、printf

用来格式话打印输出内容

(1)、格式:

printf format,item1,ietm2,…

(2)、要点

printf需要指定format;

format用于指定后面每个item的格式;

printf不能自行换行,如需换行需给定\n;

使用修饰符可以使输出格式更加美观。

(3)、format的格式指示符,以%开始,后跟一个字符

%c:显示字符的ASCII吗

%d,%i:十进制整数

%e,%E:科学计数法显示数值

%f:显示浮点数本身

%g,%G:以科学计数法格式或浮点数显示数值

%s:显示字符串

%u:显示无符号整数

%%:显示%自身

修饰符

#:字段的显示宽度

.#:取值精度

-:左对齐

=+:显示数值的符号

(4)、例:

取出系统用户的用户名和默认shell,要求用户名左对齐,占用15个字符,字符串显示;要求默认shell左对齐,占用20字符,字符串显示

awk -F: ‘{printf "%-15s %-20s\n",$1,$7}' /etcpasswd

使用显示浮点数自身(%f)的方式显示,会自动补全精度,长于精度部分将会执行四舍五入

# awk 'BEGIN{printf "%f\n",3.15}'

当使用数字来定义字段占用字符长度时,要放在其它修饰符前面;小数点后面的数字代表精度

# awk 'BEGIN{printf "%-15.2\n",3.15}'

awk之action

1、常见action

(1)、表达式 Expression

(2)、控制语句 Control statements

(3)、组合语句 Commpound statments

(4)、输入语句 Input statments

(5)、输出语句 Output statements

2、awk常见控制语句以及使用示例

(1)、if-else语句 格式:if (condition) {then body} else {else body}

# awk -F: '{if($3>=500{print $1 "is a common user"} else {print $1 "is admin or systemuser"}' /etc/passwd

uid号大于等于500的显示为普通用户,小于500的显示为管理员或系统用户。

# awk -F: '{if(NF>=8){print}}' /etc/inittab

打印显示以冒号切割形成字段大于等于8的行

(2)、while语句 格式: 格式:while (condition) {while body}

awk '{i=1;while(i<=NF){printf "%s ",$i;i+=2}; print ""}' /etc/inittab

打印输出/etc/inittab中的奇数字段

打印出字符大于等于6的字段

# awk '{i=1;while(i<=NF{if(length($i<=6){print $i};i++}}' /etc/inittab

(3)、do-while循环 格式:格式:do {do-while body} while (condition)

# awk 'BEGIN{sum=0;i=0;do{sum+=i;i+=}while{i<=100};print sum;}'

求和1-100

(4)、for循环 格式:for (variable assignment; condition; iteration process) {for body}

# awk '{for(i=1,i<=NF,i+=2){printf "%s ",$1};print ""}' /etc/inittab

打印出/etc/inittab中的每行的奇数字段

for循环还可以用来遍历数组 格式:for (i in array) {for body}

# awk 'BEGIN{"date" | getline d; split(d,test);for (i in test) print test[i]}'

break 用于在满足条件的情况下跳出循环;continue用于在满足条件时忽略后面的语句,直接返回循环的顶端

(5)、next提前结束本行处理,进入下一行处理

取uid为奇数的用户和uid

# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd

(6)、数组

关联数组

array[index-expression]index-expression:可以使用任意字符串;如果某数组元素事先不存在,那么在引用时,awk会自动创建次元素并将其初始化为空串;因此,要判断某数组是否存在某元素,必须使用“index in array”这种格式A[first]="hello awk"print A[second]要遍历数组中的每一个元素,需要使用如下特殊结构:for (var in array) {for body}期中var会遍历array的索引,而非元素的值

(7)、awk的内置函数 split(string,array[,fieldsep[,seps]])能够将string标示的字符串以fieldsep为分隔符进行切片,并切片后的结果保存至array为名的数组中;数组下表从1开始

# awk 'BEGIN{split("root:x:0:0",user,":");for (i in user) print user[i]}'

由于本人水平有限,awk的使用先总结到这里吧,在以后的使用中再深入研究。

本文分享自微信公众号 - 马哥Linux运维(magedu-Linux),作者:Silently

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-10-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 10分钟学会 linux awk命令

    ? 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读...

    小小科
  • 10分钟学会 linux awk命令

    awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为...

    小小科
  • Awk是什么?一文带运维小白快速掌握Linux Awk用法

    作者:a8 Awk、sed与grep,俗称Linux下的三剑客,它们之间有很多相似点,但是同样也各有各的特色,相似的地方是它们都可以匹配文本,其中sed和aw...

    小小科
  • awk第二课

    使用方法:awk ‘{pattern + action}’ {filenames} 尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在...

    苦咖啡
  • awk 手册

    为使读者快速掌握awk解题的模式及特性, 本手册系由一些较具代表性的范例及其题解所构成; 各范例由浅入深, 彼此间相互连贯,范例中并对所使用的awk语法及指令辅...

    sunsky
  • awk——强大的文本分析工具

    awk是一个强大的文本分析工具,awk把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

    TeamsSix
  • Linux强大的awk(一)

    最近在公司遇一个需求,要从上个月甚至是半年的日志文件中筛选出用户首次访问站点,是通过什么入口跳转进来的,访问的资源有哪些等等一些信息,无奈日志实在太大,需要经过...

    wade
  • AWK中的字段,记录和变量【Programming】

    本文为awk入门系列的第二篇文章,在本篇文章中,你可以了解到有关字段,记录和一些功能强大的awk变量。

    Potato
  • Linux三大剑客之awk

    版权声明:本文为耕耘实录原创文章,各大自媒体平台同步更新。欢迎转载,转载请注明出处,谢谢

    耕耘实录
  • Linux下使用awk批量删除共享内存

    awk 是一个强大的文本分析工具。sed 常常用于一整个行的处理,而 awk 则倾向于以空格和tab键为默认分隔符将每行切片成一个个域(也就是一列)来处理。aw...

    Dabelv

扫码关注云+社区

领取腾讯云代金券