awk是一种报表生成器,就是对文件进行格式化处理的,这里的格式化不是文件系统的格式化,而是对文件内容进行各种“排版”,进而格式化显示。awk还支持条件判断、数组、循环等各种编辑语言中所有可以使用的功能,因此我们还可以把awk称为一种脚本语言解释器。
#awk用法 awk [OPTIONS]`program`FILE1 FLIE2....
其中program:PATTERN{ACTION STATEMENT}
program:编辑语言
PATION STATEMENT:动作语言,可以是由多个语句组成,各语句间使用分号分隔;如
print,printf
OPTIONS:
-F[]:指明输入字段分隔符 例如,以“:”为分隔符,打印/etc/passwd 内容
-v VAR=VALUE:变量赋值 例如, 赋值一个变量“sex”,并打印出来
-f/PATH/FROM/AWK_SCRIPT
awk在处理文本时也是一次读取一行文本,然后根据输入分隔符进行切片,切成n个片段,然后将每一片都赋予awk内部的一个变量当中来进行保存,这些变量名为$1,$2等等一直到最后一个,awk就可以对这些片段单独处理,比如显示某一段、特定段、甚至可以对某些片段进行额外的加工处理,比如计数、运算等。
1)awk的输出命令之一:print
用法:print item1,item2,.... 例如,取出“df”命令中的以“/dev/sda”开头的占用率信息
变量:显示变量的值,可以直接使用变量的名进行引用; 例如,在“print”前后分别设置两个变量并引用,查看它们的区别,在“pringt”后设置的变量第一次不被引用
数值:无须加引号
注意点:
(1)各item之间需要使用逗号分隔;而输出的分隔符为默认为空白字符;
(2)输出的各item可以为字符串或数值,当前记录的字段($#)、变量、awk表达式;数值会被隐式转换为字符串进行输出;
(3)print后面的item省略时,相当于运行"print $0",用于输出整行;例如
awk -F: '{print}' /etc/passwd 就等同于 awk -F: '{print $0}' /etc/passwd
(4)输出空白字符:awk '{print ""}' /etc/passwd
2)变量
变量分为内建变量和自定义变量
(1)内置变量
FS:input Field Seperator,输出字符分隔符;
例如: -v FS="[,:]" 也可以使用-F:
例2:默认为空白字符
RS:input Record Seperator,输入时的行分隔符,默认的为换行符;
OFS:Output Field Seperator,输出时的字段分隔符,默认为空白字符;
ORS:Output Record Seperator,输出时的行分隔符,默认为换行符;
NF:nume of field in current record,当前行的字段数;
print NF:显示当前行的字段数
print$NF:显示当前行的第(NF-1)个字段的值
NR:name of records,行数;命令后跟的所有文件统一合计数;
FNR:行数,各文件单独计数;
FILENAME:当前正被awk读取的文件的文件名;
ARGC:awk命令行中的参数的个数;
ARGV:数组,保存了命令行参数本身;
(2)自定义变量
* -v VAR=VALUE变量名区分字符大小写;
例如:awk -v name=“mage”‘{print name}’/etc/issue
虽然这里的对象文件/etc/issue内容没有什么用,但是这里使用的是文件的行数,有多少行就显示多少个变量值。
* 在program 中自定义变量
例如:awk 'BEGIN{FS=":";f1=3}{print $f1}' /etc/issue
(3)awk 的输出命令之二: print格式化输出
* 语法:print FORMAT,item1,item2.....
* 要点:必须提供FORNAT;与print语句不同,printf不会自动换行,需要显示指定换行符:\n
* FORMAT中需要分别为后面的每个item指定一个格式符,否则item无法显示:
格式符:都以%开头,后跟单个字符:
%c:显示字符的ASCII码
%d,%i:显示十进制整数 例 :输出“/etc/passwd”第一列和第三列信息,并要求第一列左对齐15个字符并标注“Username”信息,第二列标注“UID”信息
%e,%E:科学计数法显示数值
%f:显示浮点数 例如, 将“1.73333”整数输出,“3.1111”保留两位小数输出
%g,%G:以科学计数法或浮点数格式显示数值
%s:显示为字符串 例1,输出“/etc/passwd”第一列第三列信息,并标注相应的“Username”“UID”信息
例2, 输出“/etc/passwd”第一、三列信息,并要求第一列左对齐15个字符,并输出相应的“Username”和“UID”信息
%u:显示无符号整数
%%:显示%本身
(4)awk的操作符
awk的操作符有:算术操作符、字符操作符、赋值操作符、比较操作符、模式匹配操作符、逻辑操作符、条件表达式和函数调用。
*算术操作符:实现一些算术运算,如:x+y,x-y,x*y,x/y,x^y,x%y
-x:赋值
+x:转换成数值
*字符操作符:字符串连接
*赋值操作符:通常为变量的赋值,赋值操作符有以下几种:=,+=,*=,/=,%=,^=,++,--
*比较操作符:字符串或者数值的大小比较,如:>,>=,<,<=,==,!=
*模式匹配操作符:根据右侧的模式进行匹配
~:是否能由右侧指定的模式匹配 例如, 将“/etc/passwd”中的以“root”开头的内容输出
!~:是否不能由右侧指定的模式匹配 例如,将“/etc/passwd”中的不以“root”开头的内容输出
*逻辑操作符:进行逻辑的运算
&&:与运算 例如,输出“/etc/passwd”中UID大于0且小于等于1000的用户信息
||:或运算 例如,输出“/etc/passwd”中UID等于0或小于等于100的用户信息
*条件表达式
selector?if-true-expression:if-false-expression
例如: 输出“/etc/passwd”第一列信息并对齐,当UID大于等于1000时输出“Common User”,小于1000时输出“Sys User”
*函数调用:调用函数来进行数据的处理
格式:function_name(argu1,argu2,...)
例如, 随机输出100以内的整数
(5)PATTERN模式,对那些内容进行处理
*empty:空模式,匹配所有行
*/Regular Expression/:仅将ACTION应用于能够被Regular Expression所匹配到的行:
*relational expression: 关系表达式,即结果为“真”、“假”的表达式,或者其结果能类同与“真”或“假”的表达:一般来说,其结果为非0数值或非空字符串即可类同为“真”,否则类同为“假”。
*line ranges:行范围,类似于sed或vim中的地址定界方式,如:startline,endline
*BEGIN/END:两个特殊模式
BEGIN:在文件格式化操作开始之前先执行一次操作,通常用于输出表头或作一个预处理操作
END:在文件操作完成之后,命令退出之前执行的一次操作,通常用于输出表尾或做出清理操作。
(6)常用ACTION
*EXPRESSIONS:例如变量赋值
*Compound Statements:控制语句,如if,while等
*Compound Statements:复合语句
*input statements
*output statements
(7)控制语句
*if-else 语法:if(condition){statements}[else{statements}],
例如: 输出“/etc/passwd”第一列用户信息,并要求当UID大于等于1000时输出“UserName”反之则输出“Sys User”
使用场景:对awk取得的整行或行中的字段做条件判断
*while循环 语法: while(condition){statements}
条件为“真”时循环,为“假”时退出循环
使用场景:通常用于在当前行的各字段间进行循环
例如:输出“/boot/grub/grub.conf”文件中以空格接“kernel”开头的记录,并统计每个字符的长度
*do-while 循环 语法:do {statements}while{condtion}
意义:至少执行一次循环体
*for 循环 语法:for(expr1;expr2;expr3)statement
例如: 输出“/boot/grub/grub.conf”文件中以空格接“kernel”开头的记录,并统计每个字符的长度
*break 、 continue
break[n]:退出当前循环,n是一个数字,用于制定退出几层循环;
例如, 计算从1加到88的和
continue:提前结束本轮循环而进入下一行的处理操作; 例1,计算1到100奇数的和
例2, 计算1到100偶数的和
*next:提前结束对本行文本的处理,而提前进入下一行的处理操作 例如,列出UID为奇数的用户名及UID
(8)数组
关联数组:array[index-expression]
index-expression:可以使用任意字符; 例如,统计当前各种shell的个数
如果某数组元素事先不存在,则在引用时,awk会自动创建此元素并将其值初始化为空串;因此,若要判断数组中的某元素是否存在,要使用“index in array”的方式进行判断。
数组遍历:要遍历数组中的元素,则要使用for(var_name inarray)的方式进行;此时,var_name会遍历array的每个引索,所以,要显示数组元素的值,要使用array[var_name]。
例如, 利用数组统计IP地址登录次数信息
(9)函数 分为内建函数和用户自定义函数
*内建函数:rand():返回0至1之间的一个随机数
字符串处理:length([s]):返回指定字符串的长度
sub(r,s[,t]):基于r所表达的模式来匹配字符串t中的内容,将其第一次被匹配到的内容替换为s所表示的内容
例如, 将“2018:08:29 10:08:30”的日期格式换成正确格式
gsub(r,s[,t]):基于r所表达的模式来匹配字符串t中的内容,将其所匹配到的所有内容替换为s所表示的内容
例如, 将“2018:08:29 10:08:30”的日期格式换成正确格式
split(s,a[,r]):以r为分隔符去切割字符串s,并将切割后的结果保存至a表示的数组中
substr(s,i[,n]):从s所表示的字符串中取子串,取法:从i表示的位置开始,取n个字符
时间类函数:systime()。取当前系统时间,结果形式为时间戳
例如, 正常格式输出当前的时间、日期
注意:awk的数组下标从1开始编号,而非0
上述总结基本能概括 awk的大致内容,足以应付日常的维护工作。希望这些小小的总结、示例能够给初学者带来帮助,熟练掌握awk操作,就可以畅游于Linux中。