awk命令是超级复杂的,其复杂程度比得上一种编程语言了。其实,它就是当成一种编程语言去设计的。
打印
awk最基本的用法就是输出文本内容了,直接使用print选项就可以了,以下是例子:
hope@hope:~$ tee demo.txt
In a big big world, I'm not a big big girl.
In a big big world, I'm not a big big girl.
^C
hope@hope:~$ awk '{print}' demo.txt
In a big big world, I'm not a big big girl.
当然,这么用,还不如cat呢,写起来太长了。
awk脚本
把选项写入文件中再执行才是awk的一般用法,因为awk的选项有时候太长了。这个时候使用-f选项就可以了,以下是我的实践记录:
hope@hope:~$ echo "{print}" > print.awk
hope@hope:~$ awk -f print.awk demo.txt
In a big big world, I'm not a big big girl.
hope@hope:~$ cat print.awk
{print}
hope@hope:~$
基本概念
到这里了,讲讲awk命令的基本结构吧。前文讲了,awk有两种形式,一是直接引号括起来的命令,二是-f后面加awk程序路径。再说下awk程序的基本结构吧,awk程序由多个语法块组成,每个语法块的格式都是pattern {action}这种形式。上面的例子,我们没有pattern,只有action。常见的pattern是BEGIN、END等等。但是要注意的是第一个pattern必须是BEGIN,我举个例子:
hope@hope:~/awk$ awk 'BEGIN {print "I\47m fine."}'
I'm fine.
hope@hope:~/awk$ awk 'FOO {print "I\47m fine."}'
hope@hope:~/awk$
可见如果第一个不是BEGIN,将无任何结果输出。
输出变量
awk有不少内置变量,这些变量是一开始就初始化好的,使用awk --dump-variables ‘’(注意这对单引号不能少)就可以将这些变量输出到awkvars.out文件中,下面我实践一下:
hope@hope:~$ awk --dump-variables ''
hope@hope:~$ cat awkvars.out
ARGC: 1
ARGIND: 0
ARGV: array, 1 elements
BINMODE: 0
CONVFMT: "%.6g"
ENVIRON: array, 25 elements
ERRNO: ""
FIELDWIDTHS: ""
FILENAME: ""
FNR: 0
FPAT: "[^[:space:]]+"
FS: " "
FUNCTAB: array, 41 elements
IGNORECASE: 0
LINT: 0
NF: 0
NR: 0
OFMT: "%.6g"
OFS: " "
ORS: "\n"
PREC: 53
PROCINFO: array, 30 elements
RLENGTH: 0
ROUNDMODE: "N"
RS: "\n"
RSTART: 0
RT: ""
SUBSEP: "\034"
SYMTAB: array, 28 elements
TEXTDOMAIN: "messages"
格式化输出
Java有printf,C和其他语言也有printf,同样awk也有。我们需要写一个awk脚本:
hope@hope:~/awk$ vi printf.awk
hope@hope:~/awk$ awk -f printf.awk
TEXTDOMAIN = messages
hope@hope:~/awk$ cat printf.awk
BEGIN {
printf "TEXTDOMAIN = %s\n", TEXTDOMAIN
}
hope@hope:~/awk$
这个脚本把内置变量TEXTDOMAIN的值输出了,它的值是messages。
设置变量
我们先写一个简单的awk脚本,打印变量FOO的值,脚本内容如下:
BEGIN {
printf "FOO = %s\n", FOO
}
这个时候执行是没有输出的,因为没有FOO这个变量,所以需要用-v选项设置变量,如以下例子:
hope@hope:~/awk$ awk -f printvar.awk
FOO =
hope@hope:~/awk$ awk -v FOO=BAR -f printvar.awk
FOO = BAR