awk是一种编程语言,对文本和数据进行处理,支持正则表达式,突出特点是对文本列的操作。
awk语言的最基本功能是在文件或字符串中基于指定规则来分解抽取信息,也可以基于指定的规则来输出数据。
1 awk调用的三种方式
awk调用有命令行方式、脚本执行方式和命令行调用脚本执行三种方式:
(1) awk [option] 'awk_script' input_file1 [input_file2 ...]
常用的option选项有:
-F fs: 使用fs作为输入记录的字段分隔符,如果省略该选项,awk使用环境变量FS的值(默认为空格)
-f filename: 从文件filename中读取
awk_script
-v var=value:为
awk_script设置变量
(2) 将
awk_script放入脚本文件并以#!/bin/awk -f作为首行,给予该脚本可执行权限,然后在Shell命令行下通过键入该脚本的名字进行执行。
(3) 将所有的
awk_script写入到一个单独的脚本文件,然后调用“awk -f
awk_script
_file 输入文件列表”进行执行
2 记录和域
(1) 域分隔符
域分隔符是文本列与列之间的分隔符,默认是空格或Tab。内置变量FS保存输入域分隔符值。
输出域的分隔符默认是一个空格,保存在内置变量OFS中。
修改输入域分隔符的方法为:awk -F '[ :\t]' 'print $0' passwd,表示以空格、冒号和Tab键为分隔符。
(2) 记录
记录:awk把每一个以换行符结束的行称为一个记录。
记录分隔符:默认的输入和输出的记录分隔符都是换行,保存在内置变量ORS和RS中。
变量NR:一个计数器,每处理完一条记录,NR的值就增加1.
例如:awk '{print NR, $0}' grade.txt 将打印行号和整行内容。
(3) 域
域:记录中每一列叫做域。
域标识顺序为$1,$2,$3,...,$n。$0表示整条记录,
$1表示当前记录第一列,
$n表示当前记录第n列。
3
awk_script说明
(1)模式与操作语法说明
awk脚本由模式和操作组成。
格式为:pattern {action},其中,pattern为模式,action为操作。
如果没有pattern,则action应用到全部记录,如果没有action,则输出匹配的全部记录。
(2)模式种类
(a)/正则表达式/: 使用正则表达式通配符的扩展集。常用通配符如下:
\ ^ $ . [] | () *
+:匹配其前的单个字符一次以上。
?:匹配其前的单个字符1次或0次。
(b)关系表达式。
(c)模式匹配表达式:用运算符~(匹配)和
!
~(不匹配)。
(d)范围模式:指定一个行的范围,该语法不能包括BEGIN和END模式。
(e)BEGIN:让用户指定在第一条记录被处理之前所发生的动作,通常可在这里设置全局变量。
(f)END:让用户在最后一条记录被处理之后发生的动作。
(3)操作种类
操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内,
主要有四部分:变量或数组赋值、输出命令、内置函数、控制流命令。
4 awk的运行过程
(1)awk_script的组成
awk_script可以由一条或多条awk_cmd组成,两条awk_cmd之间一般以换行符分割。
awk_cmd由两部分组成:awk_pattern {action}。
(2)awk命令的一般形式
awk 'BEGIN {action} awk_pattern1 {action} ... awk_patternN {action} END {action}' inputfile
其中BEGIN{action}和
END {action}是可选的。
(3)awk的运行过程
① 如果BEGIN区块存在,awk执行它指定的action。
② awk从输入文件中读取一行,作为一条输入记录,如果没有输入文件,则从标准输入读取。
③ awk将读入的记录分割成字段,将第1个字段放入变量$1中,第2个字段放入$2中,依次类推,$0表示整条记录。
④ 把当前记录依次与每一个awk_cmd中的awk_pattern比较,如果匹配,就执行对应的action。
⑤ 当前记录比较了所有的awk_cmd后,awk读取下一行,继续重复步骤
③和
④直到awk读取到文件尾。
⑥ 当awk读完所有的输入行后,如果存在END,就执行相应的action。
(4)inputfile可以是多于一个文件的文件列表,awk将按顺序处理列表中的每个文件。
5 内置变量与内置函数
(1)awk的内置变量
$n:
当前记录的第n个字段,字段间由FS分隔
$0:
完整的一条输入记录
ARGC:
命令行参数的数目
ARGIND:
命令行中当前文件的位置(从0开始)
ARGV:
包含命令行参数的数组
CONVFMT:
数字转换格式(默认为%.6g)
ENVIRON: 环境变量关联数组
ERRNO:最后一个系统错误的描述
FILEDWIDTHS:字段宽度列表(用空格键分隔)
FILENAME:当前文件名
FNR:同NR,但相对于当前文件
FS:字段分隔符
IGNORECASE:如果为真,则进行忽略大小写的匹配
NF:当前记录中的字段数
NR:当前记录数
OFMT:数字的输出格式
(默认为%.6g)
OFS:输出字段分隔符,默认为空格
ORS:输出记录分隔符,默认为换行符
RLENGTH:由match函数所匹配的字符串的长度
RS:记录分隔符,
默认为换行符
RSTART:由match函数所匹配的字符串的第一个位置
SUBSEP:数组下标分隔符
(2)内置字符串函数
gsub(r,s):在整个$0中用s替代r
gsub(r,s,t):在整个t中用s替代r
index(s,t):返回s中字符串t的第一位置
length(s):返回s长度
match(s,r):测试s是否包含匹配r的字符串
split(s,a,fs):用fs作为分隔符将s分成序列a
sprint(fmt,exp):返回经fmt格式化后的exp
sub(r,s):用$0中最左边最长的匹配r的子串代替s
substr(s,p):返回字符串s中从p开始的后缀部分
substr(s,p,n):返回字符串s中从p开始,长度为n的后缀部分
6 awk语法详细说明
(1)awk变量
在awk中,变量不需要定义就可以直接使用,变量类型可以是数字或字符串。
awk赋值格式为Variable=expression。例如 $awk '$1~/test/{count=$2+$3; print cout}' test.txt,上式作用是如果第一个域和test匹配,就把第二个域和第三个域相加赋给count
域变量可被赋值和修改,例如,$awk '{$2=100+$1; print $2}' test.txt
可以使用内置变量。例如,$awk '{if($1=="mary"){print NR,$1,$2,$NF}}' test.txt,该例作用为打印mary的记录数、第一个域、第二个域和最后一个域。
(2)awk数组
awk中数组叫做关联数组,下标可以是数字也可以是字符串。数组不必提前声明,也不必声明大小。数组元素根据上下文环境用0或空串来初始化。
数组下标从1开始。
用数字作下标: arr[1]="xin hua"; arr[2]="2343";
用字符串作小标:arr["first"]="xu"; arr[
"second"
]="6343";
(3)awk语句
awk有如下几种语句:
①
条件语句:if、if-else,用法与c语言中的相同。
②循环语句:while、for、do-while、special for。除special for外其他与c语言中的用法相同。
③跳转语句:break、continue,用法和c语言中的相同
④next语句:从输入文件读取一行,然后从头开始执行awk脚本。
⑤exit语句:用于结束awk程序,但不会略过END块。退出状态0表示成功,非零表示错误。
⑥
special for循环语法: for(item in arrayname) {print arrayname[item]}
(4)awk函数
awk函数分系统自带函数和用户自定义函数。如print和printf函数为awk的系统自带打印函数。
自定义函数格式如下:
function name (param1,param2,...) {...}
(5)awk运算符
awk中的运算符如c语言中的运算符类似。此外有几个特有的运算符:
~:匹配正则表达式。
!
~:不匹配正则表达式。
^、***:求幂