内容:
1、awk输出(print、printf)
2、awk变量(内建变量和定义变量)
3、awk数组
4、awk重定向输出
5、awk操作符
6、awk常见模式类型
7、awk控制及循环语句
8、awk内置函数
awk:(其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母)
awk是一款强大的报告生成器,不同于sed和grep,它的侧重点是如何把文本信息更好的展示出来,常用与统计和格式化输出。
awk相当于微型的shell,有着自己一套语法结构,例如:循环结构,数组,条件判断,函数,内置变量等功能。处理对象一般纯文本文件或纯文本信息。
在linux中用的GUN是gawk,和awk其实是同一个命令:
[19:48 root@Centos6.8~]# ll /bin/awk lrwxrwxrwx. 1 root root 4 Jul 20 02:11 /bin/awk -> gawk
语法:
awk [options] 'script' file1 file2, …
awk [options] 'PATTERN { action }' file1 file2, …:两条语法等价,上面的脚本可分为两部分,模式和动作,注意action要用{}引起来
-F:指定分割符
处理过程: 逐行读取,然后按照一定的分割符(默认空格)把该行内容进行内容分片,称为字段,每一个字段内容用$1,$2..表示,$0表示该整行,此外在awk中打印变量不需要$引用 Awk的工作方式: 1)Awk 一次读取文件中的一行 2)对于一行,按照给定的pattern的顺序进行匹配,如果匹配则执行对应的 Action 3)如果没有匹配上则不执行任何动作 4)在上诉的语法中,Pattern 和 Action 是可选的,但是必须提供其中一个 5)如果Pattern未提供,则对所有的输入行执行 Action 操作 6)如果 Action 未提供,则默认打印出该行的数据 7){} 这种 Action 不做任何事情,和未提供的 Action 的工作方式不一样 8)Action 中的语句应该使用分号分隔
工作步骤:
第一步:执行BEGIN{action;… }语句块中的语句【在读取文件前就开始打印,所以后面可以不加文件作为参数】
第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action;… }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END{action;…}语句块【后面也要加上文件作为参数】
BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块
pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块
一、常用输出说明:
1、print:
print item1, item2,…
.各项目之间使用逗号分隔,而输出时则使用输出分隔符分隔
.输出的各item可以字符串或数值、当前记录的字段、变量或awk的表达式,数值会被隐式转换为字符串后输出
.与bash的位置变量相似 print后面item如果省略,相当于print $0,若输出空白,使用pirnt ""
演示说明:
[19:17 root@Centos6.8~]# awk -F: '{print $1,$3}' /etc/passwd root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 uucp 10 operator 11 games 12 gopher 13 [19:34 root@Centos6.8~]# awk -F: '{print $1,$3,$7}' /etc/passwd root 0 /bin/bash bin 1 /sbin/nologin daemon 2 /sbin/nologin adm 3 /sbin/nologin lp 4 /sbin/nologin sync 5 /bin/sync shutdown 6 /sbin/shutdown halt 7 /sbin/halt mail 8 /sbin/nologin uucp 10 /sbin/nologin operator 11 /sbin/nologin games 12 /sbin/nologin gopher 13 /sbin/nologin
2、printf:带格式的输出
语法:printf format, item1, item2,…
说明:
.要指定format
.不会自动换行;如需换行则需要给出\n
.format用于为后面的每个item指定其输出格式
format格式的指示符都以%开头,后跟一个字符;如下:
%c: 显示字符的ASCII码;
%d, %i:十进制整数;
%e, %E:科学计数法显示数值;
%f: 显示浮点数;
%g, %G: 以科学计数法的格式或浮点数的格式显示数值;
%s: 显示字符串;
%u: 无符号整数;
%%: 显示%自身;
修饰符:
N: 显示宽度;
-: 左对齐;
+:显示数值符号;
演示说明:
[19:35 root@Centos6.8~]# awk -F: '{printf "%s%d",$1,$3}' /etc/passwd root0bin1daemon2adm3lp4sync5shutdown6halt7mail8uucp10operator11games12gopher13ftp14nobody99dbus81usbmuxd113rpc32rtkit499avahi-autoipd170vcsa69abrt173rpcuser29nfsnobody65534haldaemon68ntp38apache48saslauth498postfix89mysql27gdm42pulse497sshd74tcpdump72hill500nihao501[19:36 root@Centos6.8~]# awk -F: '{printf "%s%d\n",$1,$3}' /etc/passwd [19:36 root@Centos6.8~]# awk -F: '{printf "%s%d\n",$1,$3}' /etc/passwd root0 bin1 daemon2 adm3 lp4 sync5 shutdown6 halt7 mail8 uucp10 operator11 games12 gopher13 [19:36 root@Centos6.8~]# awk -F: '{printf "%-20s%-10s\n",$1,$3}' /etc/passwd root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 uucp 10 operator 11 games 12 gopher 13
二、awk变量
1、awk内置变量之记录变量:
FS: field separator,读取文件本时,所使用字段分隔符;
RS: Record separator,输入文本信息所使用的换行符;
OFS: Output Filed Separator:
ORS:Output Row Separator:
演示说明:
[19:42 root@Centos6.8~]# awk 'BEGIN{FS=":"}{print $1,$3}' /etc/passwd root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 uucp 10 operator 11 games 12 gopher 13
[19:43 root@Centos6.8~]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$3}' /etc/passwd root#0 bin#1 daemon#2 adm#3 lp#4 sync#5 shutdown#6 halt#7 mail#8 uucp#10 operator#11 games#12 gopher#13
2、awk内置变量之数据变量:
NR: The number of input records,awk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数;
NF:Number of Field,当前记录的field个数;
FNR: 与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数;
ARGV: 数组,保存命令行本身这个字符串,如awk '{print $0}' a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt;
ARGC: awk命令的参数的个数;
FILENAME: awk命令所处理的文件的名称;
ENVIRON:当前shell环境变量及其值的关联数组;
演示说明:
[19:45 root@Centos6.8~]# awk -F: '{print NR,$1}' /etc/issue /etc/passwd #NR统计所有文件的总行数 1 CentOS release 6.8 (Final) 2 Kernel \r on an \m 3 $(hostname) 4 `date` 5 root 6 bin 7 daemon 8 adm 9 lp 10 sync 11 shutdown 12 halt 13 mail 14 uucp 15 operator 16 games 17 gopher
[19:48 root@Centos6.8~]# awk '{print NF,$1}' /etc/issue #显示每一行的字段个数 4 CentOS 5 Kernel 1 $(hostname) 1 `date`
3、用户自定义变量
可以命令行中通过-v选项自定义变量
gawk允许用户自定义自己的变量以便在程序代码中使用,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头。gawk变量名称区分字符大小写。
演示说明:
[19:52 root@Centos6.8~]# awk -F: -v A="nihao" '{print A,$1}' /etc/passwd #同时也证明了变量的引用不需要$引用 nihao root nihao bin nihao daemon nihao adm nihao lp nihao sync nihao shutdown nihao halt nihao mail nihao uucp nihao operator nihao games nihao gopher
三、awk数组
定义方法
1:可以用数值作数组索引(下标)
array[1]=“hello awk”
Tarray[2]=“9527”
2:可以用字符串作数组索引(下标)
array[“first”]=“hello ”
array[“last”]=”awk”
array[“birth”]=”9527”
使用中 print array[1] 将得到”hello awk” 而 print array[2] 和 print[“birth”] 都将得到 ”9527” 。
例子:
split(string, array [, fieldsep [, seps ] ])
功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中
[16:44 root@Centos6.8~]#awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}' 4 test 1 it 2 is 3 a
for…in 输出,因为数组是关联数组,默认是无序的。所以通过for…in 得到是无序的数组。如果需要得到有序数组,需要通过下标获得。
[16:49 root@Centos6.8~]# awk 'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}' 1 it 2 is 3 a 4 test
过滤重复选项用法(利用真假判断):
[11:14 root@centos6.8~]# cat test 1.1.1.1,1aaa 1.1.1.1,1bbb 1.1.1.1,1ccc 2.2.2.2,2aaa 2.2.2.2,2bbb 3.3.3.3,3aaa [11:14 root@centos6.8~]# awk -F"," '!arry[$1]++' test 1.1.1.1,1aaa 2.2.2.2,2aaa 3.3.3.3,3aaa
四、输出重定向
print items > output-file:保存到文件
print items >> output-file:追加到文件
print items | command:使用管道交给某些命令处理
演示说明:
[20:02 root@Centos6.8~]# awk -F: -v A="nihao" '{print A,$1 > "/root/awktest"}' /etc/passwd [20:03 root@Centos6.8~]# cat awktest nihao root nihao bin nihao daemon nihao adm nihao lp nihao sync nihao shutdown nihao halt nihao mail nihao uucp nihao operator nihao games nihao gopher
五、awk操作符
1、算术操作符:
-x: 负值
+x: 转换为数值;
x^y:
x**y: 次方
x*y: 乘法
x/y:除法
x+y:
x-y:
x%y:
2、赋值操作符:
=
+=
-=
*=
/=
%=
^=
**=
++
—
演示说明:
[21:41 root@Centos6.8~]# awk '{ x+=$2+$3 }{print $0,x}' test 3 5 6 7 11 2 3 1 0 15 4 5 6 9 26 2 3 4 4 33 2 2 1 0 36 4 5 0 9 41 [21:41 root@Centos6.8~]# cat test 3 5 6 7 2 3 1 0 4 5 6 9 2 3 4 4 2 2 1 0 4 5 0 9
需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,应以/[=]/替代;
3、比较操作符
x < y
x <= y
x > y
x >= y
x == y
x != y
x ~ y
x !~ y
4、逻辑关系符
&&
||
5、三目表示式
selector?if-true-exp:if-false-exp
6、函数调用:
function_name (para1,para2)
演示说明:
判断UID是否大于等于500,如果为真就显示“common user”,如果为假就显示“system user”
[20:10 root@Centos6.8~]# awk -F: '{$3<500?A="system user":A="common user"}{print $1,A}' /etc/passwd #三目操作表达式 root system user bin system user daemon system user adm system user lp system user sync system user shutdown system user halt system user mail system user uucp system user operator system user games system user gopher system user
六、常见的模式类型:
1、Regexp: 正则表达式,格式为/regular expression/
2、expresssion: 表达式,其值非0或为非空字符时满足条件,如:$1~/foo/【非精准匹配】或 $1 == "VALUE"【精准匹配】,用运算符~(匹配)和!~(不匹配)。
3、Ranges: 指定的匹配范围,格式为pat1,pat2
4、BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次(常用作标题和结尾说明)
5、Empty(空模式):匹配任意输入行;
演示说明:
[20:11 root@Centos6.8~]# awk -F: '/^r/{print $1,$3}' /etc/passwd #正则表达式使用 root 0 rpc 32 rtkit 499 rpcuser 29
[20:16 root@Centos6.8~]# awk -F: 'BEGIN{print "TEST BEGIN"}/^r/{print $1,$3}END{print "TEST OVER"}' /etc/passwd #BEGIN和END的使用演示 TEST BEGIN root 0 rpc 32 rtkit 499 rpcuser 29 TEST OVER
七、控制语句
if-else
语法:if (condition) {then-body} else {[ else-body ]}
演示说明:
[10:10 root@centos6.8~]# df -P Filesystem 1024-blocks Used Available Capacity Mounted on /dev/mapper/VolGroup-lv_root 51475068 2740208 46113420 6% / tmpfs 1954768 0 1954768 0% /dev/shm /dev/sda1 487652 40654 421398 9% /boot /dev/mapper/VolGroup-lv_home 10190136 36884 9628968 1% /home [10:11 root@centos6.8~]# df -P|awk '{i=$5+0;if (i > 5){print $1,$5}}' /dev/mapper/VolGroup-lv_root 6% /dev/sda1 9%
注意:$N+0可以把$N强制去整数形式
[20:24 root@Centos6.8~]# awk -F: '{if ($3<500) {print $1,"systemm user"} else {print $1,"common user"}}' /etc/passwd root systemm user bin systemm user daemon systemm user adm systemm user lp systemm user sync systemm user shutdown systemm user halt systemm user mail systemm user uucp systemm user operator systemm user games systemm user gopher systemm user
while
语法: while (condition){statement1; statment2; …}
[20:24 root@Centos6.8~]# awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd #每个的前三个字段逐行打印 root x 0 bin x 1 daemon x 2 adm x 3 lp x 4 sync x 5 shutdown x 6 halt x 7 mail x 8 uucp x 10 operator x 11 games x 12 gopher x 13
for
语法: for ( variable assignment; condition; iteration process) { statement1, statement2, …}
演示说明:
[20:25 root@Centos6.8~]# awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd root x 0 bin x 1 daemon x 2 adm x 3 lp x 4 sync x 5 shutdown x 6 halt x 7 mail x 8 uucp x 10 operator x 11 games x 12 gopher x 13
for循环还可以用来遍历数组元素:
语法: for (i in array) {statement1, statement2, …}
case
语法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,… default: statement1, …}
break 和 continue
常用于循环或case语句中
next
提前结束对本行文本的处理,并接着处理下一行;例如,下面的命令将显示其ID号为奇数的用户:
演示说明:
[20:29 root@Centos6.8~]# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd bin 1 adm 3 sync 5 halt 7 operator 11 gopher 13
八、awk的内置函数
split(string, array [, fieldsep [, seps ] ])
功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中
length([string])
功能:返回string字符串中字符的个数;
[20:35 root@Centos6.8~]# awk -F: '{print $1,length($1)}' /etc/passwd root 4 bin 3 daemon 6 adm 3 lp 2 sync 4 shutdown 8 halt 4 mail 4 uucp 4 operator 8 games 5 gopher 6
substr(string, start [, length])
功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;
system(command)
功能:执行系统command并将结果返回至awk命令
systime()
功能:取系统当前时间,默认显示秒
[20:30 root@Centos6.8~]#awk -F: '{print $1,systime()}' /etc/passwd root 1472992355 bin 1472992355 daemon 1472992355 adm 1472992355 lp 1472992355 sync 1472992355 shutdown 1472992355 halt 1472992355 mail 1472992355 uucp 1472992355 operator 1472992355 games 1472992355 gopher 1472992355
tolower(s)
功能:将s中的所有字母转为小写
toupper(s)
功能:将s中的所有字母转为大写
[20:33 root@Centos6.8~]# awk -F: '{print $1,toupper($7)}' /etc/passwd root /BIN/BASH bin /SBIN/NOLOGIN daemon /SBIN/NOLOGIN adm /SBIN/NOLOGIN lp /SBIN/NOLOGIN sync /BIN/SYNC shutdown /SBIN/SHUTDOWN halt /SBIN/HALT mail /SBIN/NOLOGIN uucp /SBIN/NOLOGIN operator /SBIN/NOLOGIN games /SBIN/NOLOGIN gopher /SBIN/NOLOGIN
原创文章,作者:麦德良,如若转载,请注明出处:http://www.178linux.com/48407
评论列表(1条)
awk是一个很方便的文本格式化工具,这也是以后面试题必会遇到的面试题,希望下来多加练习,熟练掌握,