一、什么是awk
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它可在命令行中使用,但更多是作为脚本来使用。awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk。
二、awk的语法形式及命令选项
1.命令行方式
awk [-F field-separator] 'awk 脚本' input-file(s)
其中,’awk 脚本’ 是真正awk命令,必须包含在单引号中,[-F 域分隔符]是可选的, input-file(s) 是待处理的文件。在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指定[-F 域分隔符]的情况下,默认的域分隔符是空格。
2.shell脚本方式
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一般通过键入脚本名称来调用。相当于shell脚本首行的:#!/bin/sh可以换成:#!/bin/awk
3.将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)
其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。
awk的命令选项:
|
选项 |
含义 |
|
-F |
指定输入文件的分隔符 |
|
-f |
读取awk脚本文件 |
|
-v |
赋值自定义变量 |
三、awk的环境变量
|
变量名称 |
描述 |
|
$n |
当前记录的第n个字段,字段间由FS分隔。(列内容) |
|
$0 |
完整的输入记录。(行内容) |
|
NF |
当前记录中的字段数。(列数) |
|
NR |
当前记录数。(行数) |
|
FNR |
同NR,但相对于当前文件。 |
|
FS |
字段分隔符(默认是任何空格)。(输入列分隔符) |
|
RS |
记录分隔符(默认是一个换行符)。(输入行分隔符) |
|
OFS |
输出字段分隔符(默认值是一个空格)。(输入列分隔符) |
|
ORS |
输出记录分隔符(默认值是一个换行符)。(输出行分隔符) |
|
ARGC |
命令行参数的数目。 |
|
ARGIND |
命令行中当前文件的位置(从0开始算)。 |
|
ARGV |
包含命令行参数的数组。 |
|
CONVFMT |
数字转换格式(默认值为%.6g) |
|
ENVIRON |
环境变量关联数组。 |
|
ERRNO |
最后一个系统错误的描述。 |
|
FIELDWIDTHS |
字段宽度列表(用空格键分隔)。 |
|
FILENAME |
当前文件名。 |
|
IGNORECASE |
如果为真,则进行忽略大小写的匹配。 |
|
OFMT |
数字的输出格式(默认值是%.6g)。 |
|
RLENGTH |
由match函数所匹配的字符串的长度。 |
|
RSTART |
由match函数所匹配的字符串的第一个位置。 |
|
SUBSEP |
数组下标分隔符(默认值是\034)。 |
四、awk的运算符
|
运算符 |
描述 |
|
= += -= *= /= %= ^= **= |
赋值 |
|
?: |
C条件表达式 |
|
|| |
逻辑或 |
|
&& |
逻辑与 |
|
! |
逻辑非 |
|
~ !~ |
匹配正则表达式和不匹配正则表达式 |
|
< <= > >= != == |
关系运算符 |
|
空格 |
字符串连接 |
|
+ - |
加,减 |
|
* / & |
乘,除与求余 |
|
^ ** |
求幂 |
|
++ -- |
增加或减少,作为前缀或后缀 |
|
$ |
域引用 |
|
in |
数组成员 |
五、gawk专用正则表达式元字符
除了常用的通用元字符集外,以下几个是gawk专用的,不适合unix版本的awk。
(1)/y :匹配一个单词开头或者末尾的空字符串。
(2)/B:匹配单词内的空字符串。
(3)/<:匹配一个单词的开头的空字符串,锚定开始。
(4)/> :匹配一个单词的末尾的空字符串,锚定末尾。
(5)/w :匹配一个字母数字下划线组成的单词。
(6)/W :匹配一个非字母数字下划线组成的单词。
(7)/‘:匹配字符串开头的一个空字符串。
(8)/' :匹配字符串末尾的一个空字符串。
六、POSIX字符集
|
字符 |
含义 |
|
[:alnum:] |
代表英文大小写字符及数字,亦即 0-9, A-Z, a-z |
|
[:alpha:] |
代表任何英文大小写字符,亦即 A-Z, a-z |
|
[:lower:] |
代表小写字符,亦即 a-z |
|
[:upper:] |
代表大写字符,亦即 A-Z |
|
[:digit:] |
代表数字而已,亦即 0-9 |
|
[:blank:] |
代表空白键与 [Tab] 按键两者 |
|
[:space:] |
任何会产生空白的字符,包括空白键, [Tab], CR 等等 |
|
[:cntrl:] |
代表键盘上面的控制按键,亦即包括 CR, LF, Tab, Del.. 等等 |
|
[:graph:] |
除了空白字符 (空白键与 [Tab] 按键) 外的其他所有按键 |
|
[:print:] |
代表任何可以被列印出来的字符 |
|
[:punct:] |
代表标点符号 (punctuation symbol),亦即:" ' ? ! ; : # $... |
|
[:xdigit:] |
代表 16 进位的数字类型,因此包括: 0-9, A-F, a-f 的数字与字符 |
七、记录和域(行和列)
(1) 记录
awk把每一个以换行符结束的行称为一个记录。
记录分隔符:默认的输入和输出的分隔符都是回车,保存在内建变量RS和ORS中。
变量$0:它指的是整条记录。如$ awk '{print $0}' test将输出test文件中的所有记录。
变量NR:一个计数器,每处理完一条记录,NR的值就增加1。如$ awk '{print NR,$0}' test将输出test文件中所有记录,并在记录前显示记录号。
(2) 域
记录中每个单词称做“域”,默认情况下以空格或tab分隔。
变量NF:保存一个记录中域的数量。
(3) 域分隔符
内建变量FS保存输入域分隔符的值,默认是空格或tab。我们可以通过-F命令行选项修改FS的值。如$ awk -F: '{print $1,$5}' test将打印以冒号为分隔符的第一,第五列的内容。
可以同时使用多个域分隔符,这时应该把分隔符写成放到方括号中,如$awk -F'[:\t]' '{print $1,$3}' test,表示以空格、冒号和tab作为分隔符。
输出域的分隔符默认是一个空格,保存在OFS中。如$ awk -F: '{print $1,$5}' test,$1和$5间的逗号就是OFS的值。
八、awk的组成和执行方式
1)awk 脚本的组成:
① awk 脚本可以由一条或多条awk_cmd组成,两条awk_cmd之间一般以NEWLINE分隔
② awk_cmd由两部分组成:pattern { actions }
③ awk 脚本可以被分成多行书写,必须确保整个awk 脚本被单引号括起来。
2) awk命令的一般形式:
awk ' BEGIN { actions }
pattern1 { actions }
............
patternN { actions }
END { actions }’
input_file [input file]
其中 BEGIN { actions } 和 END { actions } 是可选的。
3) awk的运行过程:
① 如果BEGIN 区块存在,awk执行它指定的actions。
② awk从输入文件中读取一行,称为一条输入记录。(如果输入文件省略,将从标准输入读取)
③ awk将读入的记录分割成字段,将第1个字段放入变量$1中,第2个字段放入$2,以此类推。$0表示整条记录。
④把当前输入记录依次与每一个awk_cmd中pattern比较,看是否匹配,如果相匹配,就执行对应的actions。如果不匹配,就跳过对应的actions,直到比较完所有的awk_cmd。
⑤ 当一条输入记录比较了所有的awk_cmd后,awk读取输入的下一行,继续重复步骤③和④,这个过程一直持续,直到awk读取到文件尾。
⑥ 当awk读完所有的输入行后,如果存在END,就执行相应的actions。
4) input_file可以是多于一个文件的文件列表,awk将按顺序处理列表中的每个文件。
5) 一条awk_cmd的pattern可以省略,省略时不对输入记录进行匹配比较就执行相应的actions。一条awk_cmd的actions 也可以省略,省略时默认的动作为打印当前输入记录(print $0) 。一条awk_cmd中的pattern和actions不能同时省略。
6) BEGIN区块和END区块别位于awk 脚本的开头和结尾。awk 脚本中允许只有END区块或者只有BEGIN区块。如果 awk 脚本中只有BEGIN { actions } ,awk不会读取input_file。
7) awk把输入文件的数据读入内存,然后操作内存中的输入数据副本,awk不会修改输入文件的内容。
8) awk的总是输出到标准输出,如果想让awk输出到文件,可以使用重定向。
模式 pattern的分类:
|
序号 |
名称 |
含义 |
|
1 |
/正则表达式/ |
使用正则表达式匹配记录 |
|
2 |
关系表达式 |
使用关系运算符进行操作 |
|
3 |
模式匹配表达式 |
使用运算符~(匹配)和!~(不匹配) |
|
4 |
BEGIN |
指定在第一条输入记录被处理之前所发生的动作 |
|
5 |
Pattern1,pattern2 |
指定行的范围,该语法不包括BEGIN和END模式 |
|
6 |
END |
指定在最后一条输入记录被处理之后发生的动作 |
操作action由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。主要有四部份:变量或数组赋值,控制语句,输入输出指令,内置函数。
(1)变量与数组赋值
变量
· 在awk中,变量不需要定义就可以直接使用,变量类型可以是数字或字符串。
· 赋值格式:Variable = expression,如$ awk '$1 ~/test/{count = $2 + $3; print count}' test,上式的作用是,awk先扫描第一个域,一旦与test匹配,就把第二个域的值加上第三个域的值,并把结果赋值给变量count,最后打印出来。
· awk可以在命令行中给变量赋值,然后将这个变量传输给awk脚本。如$ awk -F: -f awkscript month=4 year=2004 test,上式的month和year都是自定义变量,分别被赋值为4和2004。在awk脚本中,这些变量使用起来就象是在脚本中建立的一样。注意,如果参数前面出现test,那么在BEGIN语句中的变量就不能被使用。
· 域变量也可被赋值和修改,如$ awk '{$2 = 100 + $1; print }' test,上式表示,如果第二个域不存在,awk将计算表达式100加$1的值,并将其赋值给$2,如果第二个域存在,则用表达式的值覆盖$2原来的值。再例如:$ awk '$1 == "root"{$1 ="test";print}' test,如果第一个域的值是“root”,则把它赋值为“test”,注意,字符串一定要用双引号。
· 内建变量的使用。变量列表在前面已列出,现在举个例子说明一下。$ awk -F: 'IGNORECASE=1; $1 == "MARY"{print NR,$1,$2,$NF}'test,把IGNORECASE设为1代表忽略大小写,打印第一个域是mary的记录数、第一个域、第二个域和最后一个域
数组
-
用变量作为数组下标。如:$ awk '{name[x++]=$2};END{for(i=0;i
。数组name中的下标是一个自定义变量x,awk初始化x的值为0,在每次使用后增加1。第二个域的值被赋给name数组的各个元素。在END模块中,for循环被用于循环整个数组,从下标为0的元素开始,打印那些存储在数组中的值。 因为下标是关健字,所以它不一定从0开始,可以从任何值开始。 - special for循环用于读取关联数组中的元素。格式如下:
{for (index in array){
print array [index]
}
}
$ awk '/^tom/{name[NR]=$1}; END{for(i in name){print name[i]}}' test。打印有值的数组元素。打印的顺序是随机的。
- 用字符串作为数组的下标。如:count["test"]
- 用域值作为数组的下标。如:$ awk '{count[$1]++} END{for(name in count) print name,count[name]}' test。该语句将打印$1中字符串出现的次数。它首先以第一个域作数组count的下标,第一个域变化,索引就变化。
- delete函数用于删除数组元素。如:$ awk '{line[x++]=$1} END{for(x in line) delete(line[x])}' test。分配给数组line的是第一个域的值,所有记录处理完成后,special for循环将删除每一个元素。
(2)控制语句
|
语句 |
含义 |
|
if (condition) statement [ else statement ] |
条件语句 |
|
while (condition) statement |
循环语句 |
|
do statement while (condition) |
循环语句 |
|
for (expr1; expr2; expr3) statement |
循环语句 |
|
for (var in array) statement |
循环语句 |
|
break |
退出整个循环 |
|
continue |
略过当前循环后续语句 |
|
delete array[index] |
删除数组元素 |
|
delete array |
删除数组 |
|
exit [ expression ] |
退出语句 |
(3)输入输出及重定向指令
输入指令:getline
getline从整体上来说,应这么理解它的用法:
当其左右无重定向符 | 或 < 时,getline作用于当前文件,读入当前文件的第一行给其后跟的变量var 或$0(无变量);应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到的返回结果是隔行的。
当其左右有重定向符 | 或 < 时,getline则作用于重定向输入文件,由于该文件是刚打开,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。
用法及含义:
|
用法 |
含义 |
|
getline |
读入下一行记录,更新$0,NF,NR,FNR等 |
|
getline var |
读入下一行记录到变量 var(var省略时,表示置于$0) ,更新NR,FNR |
|
getline < file |
读入文件file的一行到$0 |
|
getline var < file |
读入文件file的一行到变量 var(var省略时,表示置于$0) |
|
“command” | getline |
将shell命令command的输出作为getline的输入 |
|
“command” | getline var |
将shell命令command的输出作为getline var的输入 |
输入重定向需用到getline函数。getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。当 Pattern 为 BEGIN 或 END 时, getline 将由 stdin 读取数据, 否则由awk正处理的数据文件上读取数据。getline 一次读取一行资料,并给NF、NR和FNR等内建变量赋值。如果得到一条记录,getline函数返回1,如果到达文件的末尾就返回0,如果出现错误,例如打开文件失败,就返回-1。如:
$ awk 'BEGIN{ "date" | getline d; print d}' test。执行linux的date命令,并通过管道输出给getline,然后再把输出赋值给自定义变量d,并打印它。
$ awk 'BEGIN{"date" | getline d; split(d,mon); print mon[2]}' test。执行shell的date命令,并通过管道输出给getline,然后getline从管道中读取并将输入赋值给d,split函数把变量d转化成数组mon,然后打印数组mon的第二个元素。
$ awk 'BEGIN{while( "ls" | getline) print}',命令ls的输出传递给getline作为输入,循环使getline从ls的输出中读取一行,并把它打印到屏幕。这里没有输入文件,因为BEGIN块在打开输入文件前执行,所以可以忽略输入文件。
$ awk 'BEGIN{printf "What is your name?"; getline name < "/dev/tty" } $1 ~name {print "Found" name on line ", NR "."} END{print "See you," name "."} test。在屏幕上打印”What is your name?",并等待用户应答。当一行输入完毕后,getline函数从终端接收该行输入,并把它储存在自定义变量name中。如果第一个域匹配变量name的值,print函数就被执行,END块打印See you和name的值。
$ awk 'BEGIN{while (getline < "/etc/passwd" > 0) lc++; print lc}'。awk将逐行读取文件/etc/passwd的内容,在到达文件末尾前,计数器lc一直增加,当到末尾时,打印lc的值。注意,如果文件不存在,getline返回-1,如果到达文件的末尾就返回0,如果读到一行,就返回1,所以命令 while (getline < "/etc/passwd")在文件不存在的情况下将陷入无限循环,因为返回-1表示逻辑真。
可以在awk中打开一个管道,且同一时刻只能有一个管道存在。通过close()可关闭管道。如:$ awk '{print $1, $2 | "sort" }' test END {close("sort")}。awd把print语句的输出通过管道作为linux命令sort的输入,END块执行关闭管道操作。
输出指令:print与printf
print:
范例:
id = "BE-267"; ave = 89
print "ID# :", id, "Ave Score :"ave
(a)结果输出:
ID# : BE-267 Ave Score :89
(b)print 之后可接上字串常数(Constant String)或变量. 它们彼此间可用"," 隔开。
(c)上式中, 字串 "ID# :" 与变量 id 之间使用","隔开, 打印时两者之间会以自动OFS隔开, OFS 之值一般内定为 "一个空格"。
(d)上式中, 字串 "Ave Score :" 与变量ave之间并未以","隔开, awk会将这两者先当成字串concate在一起(变成"Ave Score :89")后,再予打印。
printf:
该指令与 C 语言中的用法相同, 可借由该指令控制输出时的格式。
语法:
printf ("输出模板字符串",参数列表)
范例:
id = "BE-2647"; ave = 89
printf("ID# : %s Ave Score : %d\n", id, ave)
(a)结果输出:
ID# : BE-2647 Ave Score : 89
(b)format 部分是由一般的字串(String Constant)及格式控制字符(Formatcontrol letter, 其前会加上一个%字符)所构成。
格式控制符: %[-][width][.prec]fmt
% : 标识一个格式控制符的开始,不可省略。
- : 表示参数输出时左对齐,可省略。
width : 一个数字,表示参数输出时占用域的宽度,可省略。
.prec : prec是一个数值,表示最大字符串长度或小数点右边的位数,可省略。
fmt : 一个小写字母,表示输出参数的数据类型,不可省略。
常见的fmt :
|
格式符 |
说明 |
|
%d |
十进制有符号整数 |
|
%u |
十进制无符号整数 |
|
%f |
浮点数 |
|
%s |
字符串 |
|
%c |
单个字符 |
|
%p |
指针的值 |
|
%e |
指数形式的浮点数 |
|
%x |
%X 无符号以十六进制表示的整数 |
|
%o |
无符号以八进制表示的整数 |
|
%g |
自动选择合适的表示法 |
输出模板字符串的字符串中必须包含格式控制符,有几个参数就要求有几个格式控制符。模板字符串中可以只有格式控制符而没有其它字符。 以上式为例,"ID# : "及" Ave Score : " 为一般字串,%s 及 %d 为格式控制字符。
(c)打印时, 一般字串将被原封不动地打印出来。遇到格式控制字符时,则依序把 format后方之 item 转换成所指定的格式后进行打印。
(d)有关的细节, 读者可从介绍 C 语言的书籍上得到较完整的介绍。
(e)print 及 printf 两个指令, 其后可使用>或>>将输出到stdout 的数据重定向到其它文件。
(4)内置函数
字符串函数:
|
函数名称 |
含义 |
|
length(str) |
返回字符串str的长度 |
|
index(str,substr) |
返回字符串substr在字符串str中第一次出现的位置,从1开始 |
|
match(str,regex) |
返回模式字符串regex在字符串str中第一次出现的位置,如果不包含,则返回值0 |
|
sprintf(fmt,exp-list) |
返回经fmt格式化后的exp |
|
substr(str, n, len) |
返回str的子字符串,其长度为len字符,从str的第n个位置开始。如果len没有出现,则传回的子字符串是从第n个位置开始至结束 |
|
sub(regex,sstr,tstr) |
将tstr中匹配正则表达式regex的第一个字符串用sstr替换 |
|
gsub(regex,sstr,tstr) |
将tstr中匹配正则表达式regex的每一个字符串用sstr替换 |
|
strtonum(str) |
转换str为数值形式 |
|
tolower(str) |
将字符串str的大写字母改为小写字母 |
|
toupper(str) |
字符串string 的小写字母改为大写字母 |
数组函数
|
函数名称 |
含义 |
|
split( str, arr, fs ) |
以fs为分隔符将字符串str分隔成一个awk数组arr,并返回arr的下标数 |
|
assort(a,b) |
对数组a的值进行排序,把排序后的下标存入新生成的数组b中,丢弃数组a下标值 |
|
asorti(a,b) |
对数组a的下标进行排序,并把排序后的下标存入新生成的数组b中 |
数学函数
|
函数名称 |
含义 |
|
atan2( y, x ) |
返回 y/x 的反正切。 |
|
cos( x ) |
返回 x 的余弦;x 是弧度。 |
|
sin( x ) |
返回 x 的正弦;x 是弧度。 |
|
exp( x ) |
返回 x 幂函数。 |
|
log( x ) |
返回 x 的自然对数。 |
|
sqrt( x ) |
返回 x 平方根。 |
|
int( x ) |
返回 x 的截断至整数的值。 |
|
rand( ) |
返回任意数字 n,其中 0 <= n < 1。 |
|
srand( [Expr] ) |
将 rand 函数的种子值设置为 Expr 参数的值,或如果省略 Expr 参数则使用某天的时间。返回先前的种子值。 |
时间函数
|
函数名称 |
含义 |
|
systime |
返回从1970年1月1日开始到当前时间(不计闰年)的整秒数 |
|
strftime |
格式化时间输出,将时间戳转为时间字符串,具体格式,见下表 |
|
mktime |
生成时间格式 |
strftime日期和时间格式说明符
|
格式 |
描述 |
|
%a |
星期几的缩写(Sun) |
|
%A |
星期几的完整写法(Sunday) |
|
%b |
月名的缩写(Oct) |
|
%B |
月名的完整写法(October) |
|
%c |
本地日期和时间 |
|
%d |
十进制日期 |
|
%D |
日期 08/20/99 |
|
%e |
日期,如果只有一位会补上一个空格 |
|
%H |
用十进制表示24小时格式的小时 |
|
%I |
用十进制表示12小时格式的小时 |
|
%j |
从1月1日起一年中的第几天 |
|
%m |
十进制表示的月份 |
|
%M |
十进制表示的分钟 |
|
%p |
12小时表示法(AM/PM) |
|
%S |
十进制表示的秒 |
|
%U |
十进制表示的一年中的第几个星期(星期天作为一个星期的开始) |
|
%w |
十进制表示的星期几(星期天是0) |
|
%W |
十进制表示的一年中的第几个星期(星期一作为一个星期的开始) |
|
%x |
重新设置本地日期(08/20/99) |
|
%X |
重新设置本地时间(12:00:00) |
|
%y |
两位数字表示的年(99) |
|
%Y |
当前月份 |
|
%Z |
时区(PDT) |
|
%% |
百分号(%) |
其他函数
|
函数名称 |
含义 |
|
close( Expression ) |
用同一个带字符串值的 Expression 参数来关闭由 print 或 printf 语句打开的或调用 getline 函数打开的文件或管道。如果文件或管道成功关闭,则返回 0;其它情况下返回非零值。如果打算写一个文件,并稍后在同一个程序中读取文件,则 close 语句是必需的。 |
|
system(Command ) |
执行 Command 参数指定的命令,并返回退出状态。等同于 system 子例程。 |
九、awk中调用shell命令
三种方式:
方式一:system(command )
方式二:print 。。。| command
方式三:command | getline
十、示例
建立待处理的文件:
[root@stone ~]# df -h > dflog
[root@stone ~]# cat dflog
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 29G 6.9G 21G 26% /
/dev/sda3 4.8G 142M 4.4G 4% /home
/dev/sda1 99M 28M 66M 30% /boot
tmpfs 203M 0 203M 0% /dev/shm
none 203M 104K 203M 1% /var/lib/xenstored
/dev/sda6 950M 24M 878M 3% /mnt/sda6
/dev/sda7 950M 73M 829M 9% /srv/myproject
/dev/scd0 2.2G 2.2G 0 100% /media/RHEL_4-U7 i386 Disc 1
(1)选择特定行、列及字段:
输出指定的行
[root@stone ~]# awk 'NR==2' dflog
/dev/sda2 29G 6.9G 21G 26% /
[root@stone ~]# awk '/home/,/boot/' dflog
/dev/sda3 4.8G 142M 4.4G 4% /home
/dev/sda1 99M 28M 66M 30% /boot
[root@stone ~]# df | awk '$2>10000000'
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 29753588 7207140 21010636 26% /
输出指定的列
[root@stone ~]# awk '{print $5}' dflog
Use%
26%
4%
30%
0%
1%
3%
9%
100%
输出指定的字段
[root@stone ~]# awk 'NR==2{print $5}' dflog
26%
[root@stone ~]# awk 'NR==2,NR==3{print $1}' dflog
/dev/sda2
/dev/sda3
输出正则表达式、关系表达式及模式匹配表达式匹配的行
[root@stone ~]# awk '/\/dev\/sda2/' dflog
/dev/sda2 29G 6.9G 21G 26% /
[root@stone ~]# awk '/^(\/dev\/sda|Filesystem)/' dflog
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 29G 6.9G 21G 26% /
/dev/sda3 4.8G 142M 4.4G 4% /home
/dev/sda1 99M 28M 66M 30% /boot
/dev/sda6 950M 24M 878M 3% /mnt/sda6
/dev/sda7 950M 73M 829M 9% /srv/myproject
[root@stone ~]# sed 's/%//g' dflog | awk '/^\/dev\/sda/{if ($5>25) print $1}'
/dev/sda2
/dev/sda1
[root@stone ~]# sed 's/%//g' dflog | awk '/^\/dev\/sda/ && $5>25'
/dev/sda2 29G 6.9G 21G 26 /
/dev/sda1 99M 28M 66M 30 /boot
[root@stone ~]# sed 's/%//g' dflog | awk '/^\/dev\/sda/{print($5>25? $1" error":$1" ok")}'
/dev/sda2 error
/dev/sda3 ok
/dev/sda1 error
/dev/sda6 ok
/dev/sda7 ok
[root@stone ~]# awk '$6~/\/home/{print $1}' dflog
/dev/sda3
[root@stone ~]# awk '$6!~/\/home/{print $1}' dflog
Filesystem
/dev/sda2
/dev/sda1
tmpfs
none
/dev/sda6
/dev/sda7
/dev/scd0
(2)BEGIN的用法
BEGIN常用于打印信息,初始化变量,包括内置变量, 在第一条输入记录被处理之前所发生的动作
[root@stone ~]# awk 'BEGIN{FS=":"}$3<5{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
[root@stone ~]# awk 'BEGIN{OFS=":"}NR==1,NR==3{print $1,$5,$6}' dflog
Filesystem:Use%:Mounted
/dev/sda2:26%:/
/dev/sda3:4%:/home
(3)END的用法
END常用于打印信息,在最后一条输入记录被处理之后所发生的动作
[root@stone ~]# df | sed -n '2,$p'| awk '{count+=$2}END{print "the total is "count}'
the total is 39459888
[root@stone ~]# df | awk 'NR>=2{count+=$2}END{print "the total is "count}'
the total is 39459888
(4)内置函数
[root@stone ~]# awk '/^\/dev\/sda/{gsub(/%/,"");if ($5>25) print $1}' dflog
/dev/sda2
/dev/sda1
[root@stone ~]# awk '/^\/dev\/sda/{gsub(/%/,"",$5);if ($5>25) print $1}' dflog
/dev/sda2
/dev/sda1