3. awk的运行过程 1) awk_script的组成: ① awk_script可以由一条或多条awk_cmd组成,两条awk_cmd之间一般以NEWLINE分隔 ② awk_cmd由两部分组成: awk_pattern { actions } ③ awk_script可以被分成多行书写,必须确保整个awk_script被单引号括起来。 2) awk命令的一般形式: awk ' BEGIN { actions } awk_pattern1 { actions } ............ awk_patternN { actions } END { actions } ' inputfile 其中 BEGIN { actions } 和 END { actions } 是可选的。 3) awk的运行过程: ① 如果BEGIN 区块存在,awk执行它指定的actions。 ② awk从输入文件中读取一行,称为一条输入记录。(如果输入文件省略,将从标准输入读取) ③ awk将读入的记录分割成字段,将第1个字段放入变量$1中,第2个字段放入$2,以此类推。$0表示整条记录。字段分隔符使用shell环境变量IFS或由参数指定。 ④ 把当前输入记录依次与每一个awk_cmd中awk_pattern比较,看是否匹配,如果相匹配,就执行对应的actions。如果不匹配,就跳过对应的actions,直到比较完所有的awk_cmd。 ⑤ 当一条输入记录比较了所有的awk_cmd后,awk读取输入的下一行,继续重复步骤③和④,这个过程一直持续,直到awk读取到文件尾。 ⑥ 当awk读完所有的输入行后,如果存在END,就执行相应的actions。 4) iput_file可以是多于一个文件的文件列表,awk将按顺序处理列表中的每个文件。 5) 一条awk_cmd的awk_pattern可以省略,省略时不对输入记录进行匹配比较就执行相应的actions。一条awk_cmd的actions 也可以省略,省略时默认的动作为打印当前输入记录(print $0) 。一条awk_cmd中的awk_pattern和actions不能同时省略。 6) BEGIN区块和END区块别位于awk_script的开头和结尾。awk_script中只有END区块或者只有BEGIN区块是被允许的。如果awk_script中只有BEGIN { actions } ,awk不会读取input_file。 7) awk把输入文件的数据读入内存,然后操作内存中的输入数据副本,awk不会修改输入文件的内容。 8) awk的总是输出到标准输出,如果想让awk输出到文件,可以使用重定向。 4.awk_pattern awk_pattern模式部分决定actions动作部分何时触发及触发actions。awk_pattern可以是以下几种类型: 1) 正则表达式用作awk_pattern: /regexp/ ① awk中正则表达式匹配操作中经常用到的字符: ^ $ . [] | () * // 通用的regexp元字符 + : 匹配其前的单个字符一次以上,是awk自有的元字符,不适用于grep或sed等 ? : 匹配其前的单个字符1次或0次,是awk自有的元字符,不适用于grep或sed等 ② 举例: awk '/ *$0.[0-9][0-9].*/' input_file 2) 布尔表达式用作awk_pattern,表达式成立时,触发相应的actions执行。 ① 表达式中可以使用变量(如字段变量$1,$2等)和/regexp/ ② 布尔表达式中的操作符: 关系操作符: < > <= >= == != 匹配操作符: value ~ /regexp/ 如果value匹配/regexp/,则返回真 value !~ /regexp/ 如果value不匹配/regexp/,则返回真 举例: awk '$2 > 10 {print "ok"}' input_file awk '$3 ~ /^d/ {print "ok"}' input_file ③ &&(与) 和 ||(或) 可以连接两个/regexp/或者布尔表达式,构成混合表达式。!(非) 可以用于布尔表达式或者/regexp/之前。 举例: awk '($1 < 10 ) && ($2 > 10) {print "ok"}' input_file awk '/^d/ || /x$/ {print "ok"}' input_file ④ 其它表达式用作awk_script,如赋值表达式等 eg: awk '(tot+=$6); END{print "total points :" tot }' input_file // 分号不能省略 awk 'tot+=$6 {print $0} END{print "total points :" tot }' input_file // 与上面等效 awk 用法例举: 变量名 含义 ARGC 命令行变元个数 ARGV 命令行变元数组 FILENAME 当前输入文件名 FNR 当前文件中的记录号 FS 输入域分隔符,默认为一个空格 RS 输入记录分隔符 NF 当前记录里域个数 NR 到目前为止记录数 OFS 输出域分隔符 ORS 输出记录分隔符 1、awk '/101/' file 显示文件file中包含101的匹配行。 awk '/101/,/105/' file awk '$1 == 5' file awk '$1 == "CT"' file 注意必须带双引号 awk '$1 * $2 >100 ' file awk '$2 >5 && $2<=15' file 2、awk '{print NR,NF,$1,$NF,}' file 显示文件file的当前记录号、域数和每一行的第一个和最后一个域。 awk '/101/ {print $1,$2 + 10}' file 显示文件file的匹配行的第二个域加10。 awk '/101/ {print $1$2}' file awk '/101/ {print $1 $2}' file 显示文件file的匹配行的第一、二个域,但显示时域中间没有分隔符。 3、df | awk '$4>1000000 ' 通过管道符获得输入,如:显示第4个域满足条件的行。 4、awk -F "|" '{print $1}' file 按照新的分隔符“|”进行操作。 awk 'BEGIN { FS="[: |]" } {print $1,$2,$3}' file 通过设置输入分隔符(FS="[: |]")修改输入分隔符。 Sep="|" awk -F $Sep '{print $1}' file 按照环境变量Sep的值做为分隔符。 awk -F '[ : |]' '{print $1}' file 按照正则表达式的值做为分隔符,这里代表空格、:、TAB、|同时做为分隔符。 awk -F '[][]' '{print $1}' file 按照正则表达式的值做为分隔符,这里代表[、]
awk的调用方式为 :
awk [opion] 'awk_script' input_file1 [input_file2 ...]
其中awk_script 必须用单引号引住, 格式为 awk_pattern{action}
awk_pattern用于匹配行,action用于对行进行处理,可以省略其中一个,但不能两个都省略。
awk_pattern可以是正则表达式(用//包含,如/9/),可以是awk_pattern表达式,可以是其他表达式
例子:
awk '/9/{print $1}' t1 匹配t1文件中所有含有9的行,并输出第一列
awk '$1<10 {print $1}' t1 匹配所有第一列小于10的行,并输出第一列
awk '$1<10 && $1>5 {print $1}' t1 小于10而且大于5
awk ' {print $1+10}' t1 第一列加10
awk -F '|' '{print $2}' t3 -F 用‘|’作为分隔符,默认是空格
awk -F 'cc' '{print $2}' t3 -F 后面可以接正则表达式,这里以cc为分隔符
awk '{for(i=1;i<5;i++){print $i}}' t3 可以在action模块中插入if和for和while等语句
df /data/database/mysql |awk 'END{print $5}' 获取某个目录相应的分区的硬盘使用率