Linux awk几乎是一种自解释的独立编程语言。它的最基本的功能就是在文件和字符串中基于指定规则浏览和抽取信息。有三种方式可以调用awk,第一种是命令行方式,例如:
Java代码
awk [-F seperator-fields] 'commands' input-file
[java]
awk [-F seperator-fields] 'commands' input-file
commands是真正的awk命令,即由一系列的大括号组成,-F 域分割符 这个是可选的,awk默认采用空格来分割,但是对于/etc/passwd这样的文件,可能就需要采用冒号: 这样的分割符号。
第二种方式是将所有的awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它
第三种方式是将所有awk命令插入一个单独的文件,然后输入以下命令来调用:
Java代码
awk -f awk-script-file input-files
//-f 选项指明在文件awk_script_file的awk脚本,input_file是使用awk进行浏览的文件名
[java]
awk -f awk-script-file input-files
//-f 选项指明在文件awk_script_file的awk脚本,input_file是使用awk进行浏览的文件名
awk语言中采取一种特别的方式来访问文件--域和记录
awk执行的时候,将其浏览域标记为$1 $2 ... $n ,使用$1,$3表示将参考第一个域和第三个域,这里采用逗号来分隔开不同的域,如果希望打印全部的域,可以直接使用$0,而不必一个一个域的去指定。例如,打印/etc/passwd文件里的第一列(也即登录的用户名)
Java代码
awk -F : '{ print $1 }' /etc/passwd
[java]
awk -F : '{ print $1 }' /etc/passwd
将输出该文件的第一列
任何awk语句都是由模式和动作来组成,模式部分决定动作语句何时触发及触发事件,处理即对数据采取的动作,如果省略模式,动作将时刻保持执行状态。
模式可以是任意的正则表达式语句或其他条件语句,它包括两个特殊的字段,BEGIN和END,BEGIN使用在任何文本浏览动作之前,常用来打印行头,而END用在所有文本浏览动作之后,常用来打印文本总数和结尾状态标志。
例如:有这样一个文件:
Java代码
[chenwu@localhost unit9-awkIntroduce]$ cat grade.txt
chenwu 05/99 4811
mary 02/22 1231
tom 09/15 1182
[java]
[chenwu@localhost unit9-awkIntroduce]$ cat grade.txt
chenwu 05/99 4811
mary 02/22 1231
tom 09/15 1182
下面的语句将打印一个常用的报表头,及第一列和第三列。
Java代码
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print "name""\t""id"} {print $1"\t"$3}' grade.txt
name id
chenwu 4811
mary 1231
tom 1182
[java]
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print "name""\t""id"} {print $1"\t"$3}' grade.txt
name id
chenwu 4811
mary 1231
tom 1182
如果加上行尾,则应该是这样:
Java代码
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print "name""\t""id"} {print $1"\t"$3} END {print "end-of-report"}'
grade.txt >grade.report
[chenwu@localhost unit9-awkIntroduce]$ ls
grade.report grade.txt
[chenwu@localhost unit9-awkIntroduce]$ cat grade.report
name id
chenwu 4811
mary 1231
tom 1182
end-of-report
[java]
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print "name""\t""id"} {print $1"\t"$3} END {print "end-of-report"}'
grade.txt >grade.report
[chenwu@localhost unit9-awkIntroduce]$ ls
grade.report grade.txt
[chenwu@localhost unit9-awkIntroduce]$ cat grade.report
name id
chenwu 4811
mary 1231
tom 1182
end-of-report
在碰到awk错误的时候,应该这样查找错误:
1:查找命令commands是否被单引号括起来
2:查找commands内大括号是否匹配
尝试着加入条件判断:
这里打印名称为mary的行. 使用if($x(第几列)~ 正则表达式) 语句
Java代码
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print "name""\t""ID"} {if($1 ~/mary/) print $0}
END {print "end-of-report"}' grade.txt
name ID
mary 02/22 1231
end-of-report
[java]
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print "name""\t""ID"} {if($1 ~/mary/) print $0}
END {print "end-of-report"}' grade.txt
name ID
mary 02/22 1231
end-of-report
而取反的方式是if($1 !~ /mary/)
在awk中组合条件语句与javascript很类似,都是使用||或者&& ,这与传统的shell -o 或者 -a 不同。
同时在awk中提供了很多内置变量,可以方便的运用。常用的有以下几个:
NF 域的个数 NR 已读记录的个数 FILENAME表示文件名
例如:
Java代码
[chenwu@localhost unit9-awkIntroduce]$ awk '{print NF,NR,$0} END{print FILENAME}' grade.txt
3 1 chenwu 05/99 4811
3 2 mary 02/22 1231
3 3 tom 09/15 1182
grade.txt
[java]
[chenwu@localhost unit9-awkIntroduce]$ awk '{print NF,NR,$0} END{print FILENAME}' grade.txt
3 1 chenwu 05/99 4811
3 2 mary 02/22 1231
3 3 tom &nbs
补充:软件开发 , Java ,