本文编辑整理自: http://apps.hi.baidu.com/share/detail/6533091
一、前言
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk。awk语言的最基本功能是在文件或字符串中基于指定规则来分解抽取信息,也可以基于指定的规则来输出数据。完整的awk脚本通常用来格式化文本文件中的信息。
二、基本语法
awk [opion] 'awk_script' input_file1 [input_file2 ...]
awk的常用选项option有:
①
-F fs : 使用fs作为输入记录的字段分隔符,如果省略该选项,awk使用环境变量IFS的值
②
-f filename : 从文件filename中读取awk_script
③ -
v var=value : 为awk_script设置变量
awk有三种运行方式:
第一种,把awk的脚本命令直接放在命令中。
第二种,把awk的所有的脚本命令放在一个脚本文件中,然后用-f选项来指定要运行的脚本命令文件。
第三种,将awk_script放入脚本文件并以
#!/bin/awk -f 作为首行,给予该脚本可执行权限,然后在shell下通过键入该脚本的脚本名调用之。
三、awk脚本
awk
脚本可以由一条或多条
awk_cmd
组成,对于多个
awk_cmd
,一
个awk_cmd
完成后,应该另起一行,以便进行隔。
awk_cmd
由两部分组成:
awk_pattern { actions }
。
另外,在
awk
命令中直接使用
awk_script
时,
awk_script
也可以被分成多行书写,但必须确保整个
awk_script
被
单引号
括起来。
awk命令的一般形式:
awk '
BEGIN
{ actions }
awk_pattern1 { actions }
............
awk_patternN { actions }
END
{ actions }
' inputfile
其中 BEGIN { actions } 和 END { actions } 是可选的。
在awk脚本中可以使用AWK本身内置变量,如下:
ARGC
命令行变元个数
ARGV
命令行变元数组
FILENAME
当前输入文件名
FNR
当前文件中的记录号
FS
输入域分隔符,默认为一个空格
RS
输入记录分隔符
NF
当前记录里域个数
NR
到目前为止记录数
OFS
输出域分隔符
ORS
输出记录分隔符
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。
1)i
nput_file可以是多于一个文件的文件列表,awk将按顺序处理列表中的每个文件。
2)
一条
awk_cmd
的
awk_pattern
可以省略,省略时不对输入记录进行匹配比较就执行相应的actions。一条awk_cmd的actions 也可以省略,省略时默认的动作为打印当前输入记录,即{print $0} 。一条awk_cmd中的awk_pattern和actions
不能同时省略
。
3)
BEGIN区块
和
END区块
别位于awk_script的开头和结尾。
awk_script
中只有
END区块
或者只有
BEGIN区块
是被允许的。如果awk_script中只有BEGIN { actions } ,awk不会读取input_file。
4)
awk
把输入文件的数据读入内存,然后操作内存中的输入数据副本,
awk
不会修改输入文件的内容。
5)
awk
的总是输出到标准输出,如果想让
awk
输出到文件,可以使用重定向。
3.1.awk_pattern
awk_pattern
模式部分决定
actions
动作部分何时触发及触发
actions
。
awk_pattern
可以是以下几种类型
:
1) 正则表达式用作
awk_pattern
:
/
regexp
/
注意,
正则表达式
regexp
必须被
/
包起来
awk中正则表达式匹配操作中经常用到的字符:
\ ^ $ . [] | () * //
:通用的regexp元字符
+
: 匹配其前的单个字符一次以上,是awk自有的元字符,不适用于grep或sed等
?
: 匹配其前的单个字符1次或0次,是awk自有的元字符,不适用于grep或sed等
关于正则表达式的更多内容请参《
正则表达式》
举例
:
awk '
/
*
\$
0
\.
[0-9][0-9]
.
*
/
' input_file
比如,行内容为
$0.99. helllo
的行就可以和上面的正则表达式相配
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 $0 "ok"}' input_file
awk '
/
^d
/
||
/
x$
/
{print $0 "ok"}' input_file
④ 其它表达式用作awk_script,如赋值表达式等
举例
:
awk '(tot+=$6); END{print "total points :" tot }' input_file
// 分号不能省略
awk 'tot+=$6 {print $0} END{print "total points :" tot }' input_file
// 与上面等效
当使用赋值表达式时,表示如果赋值后的变量是数字的话,如果为非0,就匹配,否则不匹配;如果为字符串的话,非空就为匹配,否则不匹配。