文本三剑客之awk

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文本三剑客之awk相关的知识,希望对你有一定的参考价值。

awk是一种报告生成器,能够格式化输出文本,有着多种版本,我们主要使用的是GNU awk,通常也称之为gawk,可以进行模式扫描和处理的语言。

1.awk语法

awk的基本语法如下:

awk [options] ‘program’ var=value file…
awk [options] -f programfile var=value file…
awk [options]  ‘BEGIN{ action;… } pattern{ action;… } END{ action;… }‘  file

第一句的语法是awk加上选项,加上程序部分,加上变量,最后是要操作的文件路径
第二句的语法是awk加上选项,接一个-f,后面是程序部分,不过此处的程序不在是一串代码,而是一个文件,这个文件的内容是程序代码,后面是变量和要操作的文件名
第三句的代码是awk加上选项,后面接的是程序部分,它由BEGIN,pattern,END三部分中的部分组成,后面接的是要操作的文件名。
程序代码部分是需要用单引号或者双引号引起来,这样能够将awk的代码和shell语言分隔开。
BEGIN部分
BEGIN部分代码是在程序执行过程中最先被执行的部分,是可以选择执行的,他执行是在读文件之前,所以单独的一个BEGIN是不需要文件的,例如:

awk ‘BEGIN{print“hello world”}’

执行结果如下:
技术分享图片
BEGIN主要用来打印生成表的表头等其他语句。
pattern部分
pattern是对文件处理的部分,他会按照记录一个一个的扫描,知道所以的记录都被扫描过结束,pattern是程序中最重要的部分,他也是可以选择执行的,如果没有pattern部分,则默认执行{print},即打印文件中的每一行,读取文件中的每一行都会执行该语句,例如:

awk ‘1‘ /etc/fstab

执行结果如下:
技术分享图片
END部分
END部分语句是在读至输入流末尾时执行的语句,这部分代码也是可以选择执行的,比如打印所有行的分析结果这类的信息汇总,例如

awk ‘{print}END{print "hello world"}‘ /etc/fstab

执行结果如下:
技术分享图片

2.分割符、域和记录

awk执行时,由分隔符分隔的字段(域)标记$1,$2..$n称为域标识,我们可以选择打印输出这些域的内容。例如

awk -F‘ ‘ ‘{print $1,$3}‘ /etc/fstab

执行结果如下:
技术分享图片
$0为所有域,例如:

awk -F‘ ‘ ‘{print $0}‘ /etc/fstab

执行结果如下:
技术分享图片
文件按记录来进行执行awk操作,在shell中每一行称为一条记录,awk中可以指定特定的文件记录分割符。在shell中$是引用变量,而在awk中$的作用是引用记录中的第几个片段。
省略action,则默认执行 print $0 的操作,如果程序代码中的内容为空或0,是什么都不会执行的,因为空也是0,如果是非0,就默认执行{print},例如:

awk -F‘ ‘ ‘0‘ /etc/fstab

执行结果如下:
技术分享图片
-F选项可以指定记录中域的分割符,可以是任何东西。

3.awk内置变量

1.FS:输入字段分隔符,默认为空白字符,例如:

awk ‘{print $1"  "$3}‘ /etc/fstab

执行结果如下:
技术分享图片
我们设置输入字段分隔符为/,例如:

awk -v FS=‘/‘ ‘{print $1"  "$3}‘ /etc/fstab

执行结果如下:
技术分享图片
因为FS是内置变量,所以在awk中可以引用,例如

awk -v FS=‘/‘ ‘{print $1FS$3}‘ /etc/fstab

执行结果如下:
技术分享图片
2.OFS:输出字段分隔符,默认为空白字符,复制出一部分password内容用来演示,例如:
技术分享图片

awk -v FS=: -v OFS=# ‘{print $1,$3}‘ /app/passwd

执行结果如下:
技术分享图片
","表示引用输出字段分割符,默认是空格,当定义了OFS后就是OFS了。
3.RS:输入记录分隔符,指定输入时的换行符,原换行符仍有效,例如:

awk -v FS=: -v RS=‘nologin‘ ‘{print $1,$3}‘ /app/passwd

执行结果如下:
技术分享图片
可以看出整个文件被nologin分割为5段,称为5个记录,然后每个记录以:作为域分割符,取出第1个域和第3个域。原有的换行符不再作为输入记录分割符,但是仍旧有效,输出的内容中依然可以换行,例如:

awk -v OFS=‘:‘ -v FS=: -v RS=‘sbin‘ ‘{print $1,$3}‘ /app/passwd

执行结果如下:
技术分享图片
/nologin加换行符和daemon被作为第二个记录的第一个域输出,域之间以:作为分割符,2是第三个域的内容。
4.ORS:输出记录分隔符,输出时用指定符号代替输入记录分割符,例如:

awk -v ORS=‘#‘ -v RS=‘/sbin‘ ‘{print}‘ /app/passwd

执行结果如下:
技术分享图片
可以看到原来的输入记录分割符‘/sbin’在输出时被#替换,原来的换行符还有效,只是不作为记录分割符
5.NF:字段数量,例如:

awk -v FS=: -v RS=‘/sbin‘ ‘{print NF}‘ /app/passwd

执行结果如下:
技术分享图片
记录按“/sbin”分割,而字段或者域用:分割。
6.NR:记录号,例如:

awk -v RS=‘/sbin‘ ‘END{print NR}‘ /app/passwd

技术分享图片
记录被“/sbin”分割,然后用END生成统计结果,一共有11条记录
7.FNR:各文件分别计数,记录号,例如:

awk -v RS=‘/sbin‘ ‘{print FNR};END{print NR}‘ /app/passwd /app/passwd

技术分享图片
记录以"/sbin"分割,两次对/app/passwd计数,最后用END生成统计结果,共有22条。
8.FILENAME:当前文件名,例如:

awk ‘{print FILENAME}‘ /app/passwd

技术分享图片
9.ARGC:命令行参数的个数,例如:

awk ‘END{print ARGC}‘ /app/passwd /etc/passwd

执行结果如下:
技术分享图片
一共有三个参数,第一个是awk,第二个是/app/passwd第三个是/etc/passwd
10.ARGV:数组,保存的是命令行所给定的各参数,例如:

 awk ‘END{print ARGV[0] }‘ /app/passwd /etc/passwd

打印命令行第一个参数,执行结果如下:
技术分享图片

awk ‘END{print ARGV[ARGC-1] }‘ /app/passwd /etc/passwd

打印命令行的最后一个参数,执行结果如下:
技术分享图片

4.自定义变量

自定义变量的方法如下:

awk -v test=123 ‘BEGIN{print test}‘

如上,定义了一个test变量,执行结果如下:
技术分享图片
还可以在程序中定义变量,例如:

awk -v ‘test=134{print test,tooth;tooth=23}‘ /etc/fstab

执行结果如下:
技术分享图片

5.格式化输出

格式化输出使用的是printf,当使用printf时,必须要为每一个输出指定格式,例如:

awk -F: ‘{printf "UNAME:%-15s UID:%s
",$1,$3}‘ /app/passwd

执行结果如下:
技术分享图片

%s表示显示字符串,-15表示左对齐15字符,
代表换行,下面是常用的格式化控制符:
%c: 显示字符的ASCII码
%d: %i: 显示十进制整数
%e: %E:显示科学计数法数值
%f: 显示为浮点数
%g: %G:以科学计数法或浮点形式显示数值
%s: 显示字符串
%u: 无符号整数
%%: 显示%自身

还有一些修饰符:

    #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f
-: 左对齐(默认右对齐) %-15s
+:显示数值的正负符号 %+d

6.操作符

1.算术操作符

+加-减*乘/除%取余^乘方
-x转换为负数
+x转换为数值

2.赋值操作符

=, +=, -=, *=, /=, %=, ^=
++, --

3.逻辑操作符

&&逻辑与
||逻辑或
!逻辑非

4.比较操作符

==等于
!=不等于
>大于
>=大于等于
<小于
<=小于等于

5.模式匹配符

~:左边是否和右边匹配包含
!~:是否不匹配

例如:

awk -F: ‘$0 ~ /root/    {print $1}‘  /etc/passwd

执行结果如下:
技术分享图片
awk支持正则表达式,例如

awk -F: ‘$0 ~ "^root"    {print $1}‘  /etc/passwd

技术分享图片
6.三目表达式
三目表达式的格式如下:

判断?语句1:语句2

最开始先进行判断,如果判断结果为真,则执行语句1,如果判断结果为假,则执行语句2,例如:

awk ‘BEGIN{1>3?a=1:a=3;print a}‘

执行结果如下:
技术分享图片

7.awk action

1.awk循环
while循环
循环在条件为真开始循环,在条件为假时结束循环,例如:

awk  ‘BEGIN{i=1;while(i<10){ print i;i++}}‘

执行结果如下:
技术分享图片
for循环
循环在满足for的条件时开始循环,在不满足for条件时结束循环,例如:

awk ‘BEGIN{for(i=1;i<10;i++)print i}‘

执行结果如下:
技术分享图片
2.awk选择
if选择
如果满足if后面条件,则执行之后的语句,否则不执行,进行其他的if判断,最多有一个if被执行,例如:

awk -v i=9 ‘BEGIN{if(i<=5){print "小于等于5"}else if(i>5 && i<=10){print "大于5小于等于10"}else{print "大于10"}}‘

执行结果如下:
技术分享图片
3.awk控制
continue控制
continue控制是结束当前这一次循环,直接进行下一次循环,例如:

awk ‘BEGIN{i=0;while(i<10){i++;if(i==5){continue} print i}}‘

执行结果如下:
技术分享图片
当执行到i=5时,结束了循环,没有输出5,继续下一次循环,即i=6的循环。
break控制
break控制是结束当前这一层循环,返还到上一级,例如:

awk ‘BEGIN{i=0;while(i<10){i++;if(i==5){break} print i}}‘

技术分享图片
当执行到i=5时,结束了当前循环,退出当前的循环,没有再进行打印5的操作以及之后的循环。
4.awk数组
我们常常用数组来看文件中某一列内容的重复次数,例如:

awk -F: ‘{line[$7]++}END{for(i in line){print i,line[i]}}‘ /etc/passwd

执行结果如下:
技术分享图片
5.awk函数
awk函数一般是写在一个文件中的,当需要时调用这个函数文件,例如:

function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}

技术分享图片
执行结果如下:
技术分享图片
6.awk脚本
在awk中可以用system调用shell命令,例如:

awk ‘BEGIN{score=100; system("echo  your score is " score) }‘

执行结果如下:
技术分享图片
我们可以用执行脚本的方法来执行awk例如:

#!/bin/awk –f
{if($3>=1000)print $1,$3}

将上面代码写入文件:
技术分享图片
加上执行权限,并执行,结果如下:
技术分享图片

以上是关于文本三剑客之awk的主要内容,如果未能解决你的问题,请参考以下文章

文本处理三剑客之AWK

文本三剑客之awk

文本处理三剑客之gawk

linux 文本三剑客之awk

文本三剑客之awk进阶篇

文本三剑客之awk