好文章http://www.linux.gov.cn/shell/awk.htm
一、处理方式
awk用于处理文本文件,awk的处理文本文件的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出 (屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。
二、常用命令格式
1.awk [options] 'script' var=value files
2.awk [options] -f scriptfile var=value files
三、常用命令行选项
-F 域分隔符,如: -F,
-v var=value 传变量值
-f scriptfile 从脚本文件中读取命令
四、脚本组成
awk脚本由模式和操作组成
pattern {action}
两者是可选的
如果没有模式,则操作应用到全部记录
如果没有操作,则输出匹配全部记录
1.模式
-
/正则表达式/:使用通配符的扩展集。
-
如:awk '/test/{print $0;}' file 行包含test,则输出行
-
关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较。
- 如:awk -F, '$2 == 1 {print $0;}' file 以逗号为分隔符,如果第二个域等于1,则输出整个行
-
模式匹配表达式:用运算符~(匹配)和~!(不匹配)。
-
如:awk '$1~/test/{print $0;}' file 行中匹配有test,则输出行
-
模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。
- 如:awk '/test1/,/test2/{print $0;}' file 将匹配模式test1和test2间的行输出
-
BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。
-
如:awk 'BEGIN{var="test";}END{print var;}' file 开始时给var赋值,结束时打印var
-
END:让用户在最后一条输入记录被读取之后发生的动作。
-
如:awk 'BEGIN{var="test";}END{print var;}' file 开始时给var赋值,结束时打印var
2.操作
-
变量、数组赋值
- 如:var=1 name[1]=0 name[1]=1 var="test"等
-
输出命令
- 如:print等
-
函数调用
- 如:index,substr等
-
控制流
- if if-else for while等
五、awk内部变量
例如:有一个文件test和test1(两个文件一样),其中有如下行:
Test,1
test,2
abc,3
test,4
b,5
c,1
变量 | 描述 |
---|---|
$n | 当前记录的第n个字段,字段间由FS分隔。
awk -F, '{print $1}' test 打印第一个域(列) |
$0 | 完整的输入记录。
awk -F, '{print $0}' test 打印文件中的每一行 |
ARGC | 命令行参数的数目。
awk -F, 'END{print ARGC}' test 参数为2个,awk和test |
ARGIND | 命令行中当前文件的位置(从0开始算)。
awk -F, 'END{print ARGIND}' test test在命令行的位置为1 |
ARGV | 包含命令行参数的数组。
awk -F, 'END{print ARGV[0],ARGV[1]}' test 打印awk test |
CONVFMT | 数字转换格式(默认值为%.6g)
awk 'BEGIN{CONVFMT="%.6g"}END{a=172.345678;b=a"";print b;}' test 将数字a转换成字符串b时的转换格式 输出:172.346 |
ENVIRON | 环境变量关联数组。
awk -F, 'END{for(var in ENVIRON){print var,ENVIRON[var]}}' test 打印环境变量的名和值 |
ERRNO | 最后一个系统错误的描述。 |
FIELDWIDTHS | 字段宽度列表(用空格键分隔)。替换FS分隔符
awk 'BEGIN{FIELDWIDTHS="1 2 1"}{print $1,$2}' test 打印出: T es |
FILENAME | 当前文件名。
awk -F, '{print FILENAME}' test test1 打印出6个test和6个test1 |
FNR | 同NR,但相对于当前文件。
awk -F, '{print FNR,$0}' test test1 打印出: 1 Test,1 |
FS | 字段分隔符(默认是任何空格)。
awk 'BEGIN{FS=","}{print FNR,$1}' test 打印出: 1 Test |
IGNORECASE | 如果为真,则进行忽略大小写的匹配。
awk 'BEGIN{FS=",";IGNORECASE=1}/test/{print FNR,$1}' test 打印出: 1 Test |
NF | 当前记录中的字段数。
awk 'BEGIN{FS=","}{print $0,"Number of Fields="NF}' test 打印出: Test,1 Number of Fields=2 |
NR | 当前记录数。
awk 'BEGIN{FS=","}{print $0,NR}' test test1 打印出: Test,1 1 |
OFMT | 数字的输出格式(默认值是%.6g)。
awk 'BEGIN{OFMT="%.4g"}END{print 172.345678;}' test 打印出:172.3 |
OFS | 输出字段分隔符(默认值是一个空格)。
awk 'BEGIN{FS=",";OFS=":"}{print $1,$2}' test 以冒号为分隔符输出 |
ORS | 输出记录分隔符(默认值是一个换行符)。
awk 'BEGIN{FS=",";OFS=":";ORS="/n/n"}{print $1,$2}' test 输出以/n/n为行分隔符 |
RLENGTH | 由match函数所匹配的字符串的长度。
awk 'END{match("hello test!",/st!$/);print RSTART,RLENGTH}' test 打印出:9 3 (从1开始数) |
RS | 记录分隔符(默认是一个换行符)。
awk 'BEGIN{RS=","}{print $0;}' test 打印出: Test 一个空行 |
RSTART | 由match函数所匹配的字符串的第一个位置。
awk 'END{match("hello test!",/st!$/);print RSTART,RLENGTH}' test 打印出:9 3 (从1开始数) |
SUBSEP | 数组下标分隔符(默认值是/034)。
awk 'BEGIN{array[0,0]="test1";array[0,1]="test2";}END{for(var in array){print var,SUBSEP,array[var]}}' test 输出:其中SUBSEP替换了0,0中的逗号 00 test1 |