文章目录
2 运行awk
本文介绍如何运行awk的命令行选项,以及awk和gawk如何处理非选项参数。
2.1 awk调用方法
有两种方法调用awk:使用显示程序或者一个或多个程序文件。两种形式的模板如下:
awk [options] -f progfile [--] file …
awk [options] [--] 'program' file …
可以使用空程序调用awk:
awk '' datafile1 datafile2
然而,这样做没有什么意义。在program为空时,awk悄然退出。如果在命令行中指定了--lint,gawk将发出程序为空的警告。
# awk --lint '' anaconda-ks.cfg install.log
awk: warning: empty program text on command line
awk: warning: source file does not end in newline
awk: warning: no program text at all!
2.2 命令行中的常用参数
这里的options就是上一节模板中的options,后面统称为选项。选项以短划线开始,由单个字符组成。如果该选项采用参数,则关键字后面紧跟等号(“=”)和参数值,或者关键字和参数值之间用空格分隔。如果有一个值的特定选项被多次给定,则它取最后一个值。
awk的每个长选项都有一个对应的POSIX样式的短选项,长短选项在所有情况中都是可互换的。
2.2.1 -F参数
- -F fs
--field-separator fs
将fs设置为字段分隔符。字段分隔符是单个字符或正则表达式,awk通过字段分隔符将输入记录拆分为各个字段。
示例:
如果字段分隔符为’oo’,则输入记录:
moo goo gai pan
被拆分成3个字段:‘m’,’ g’,’ gai pan’。注意第二个和第三个字段值中的前导空格。
在awk程序中,可以使用赋值运算符“=”更改字段分隔符(FS)的值。通常,更改分隔符的正确时间在处理任何输入之前,这样就可以用正确的分隔符读取第一条记录。为此,请使用BEGIN模块。
示例:使用字符串“,”对输入记录进行分隔,并提取第二字段。
第一种方法,使用BEGIN模块
awk 'BEGIN { FS = "," } ; { print $2 }'
输入相关文本,得到分隔后的第二字段
# cat test.txt
John Q. Smith, 29 Oak St., Walamazoo, MI 42139
# awk 'BEGIN { FS = "," } ; { print $2 }' test.txt
29 Oak St.
第二种方法,使用 -F 或 --field-separator 选项
# awk -F ',' '{ print $2 }' test.txt
29 Oak St.
# awk --field-separator ',' '{ print $2 }' test.txt
29 Oak St.
关于FS还有很多细节,在此不展开了。
2.2.2 -f参数
- -f source-file
--file source-file
从源文件读取awk程序。
示例:
# cat systime.awk
BEGIN {
print "in awk namespace, systime() =", systime()
}
# awk -f systime.awk
in awk namespace, systime() = 1574773742
2.2.3 -v参数
- -v var=val
--assign var=val
在程序开始执行之前,将变量var设置为值val。此类变量值在BEGIN规则中可用。
-v选项只能设置一个变量,但可以多次使用,每次都设置另一个变量,例如:‘awk -v foo=1 -v bar=2 …’
注意:使用-v设置内置变量的值可能会导致意外的结果。awk将根据需要重置这些变量的值,可能会忽略人为设定的初始值。
示例:
输出2个示例文件的不同字段(示例文件见“关于awk命令的一些知识(第一章)”)
# awk '{ print $n }' n=4 inventory-shipped n=2 mail-list
15
24
34
63
29
75
67
47
37
68
82
61
64
80
70
74
555-5553
555-3412
555-7685
555-1675
555-0542
555-2912
555-1234
555-6699
555-6480
555-3430
555-2127
-v选项及其赋值必须在所有文件名参数以及程序文本之前。另一种写法如下:
# awk -v n=4 '{ print $n }' inventory-shipped n=2 mail-list
2.2.4 -d参数
- -d[file]
--dump-variables[=file]
打印全局变量类型和最终值的排序列表到文件。如果没有提供文件,请将此列表打印到当前目录中名为awkvars.out的文件中。如果提供了文件,-d和文件之间不允许有空格。
示例:
# awk -d '{print $0}' mail-list
melia 555-5553 amelia.zodiacusque@gmail.com F
Anthony 555-3412 anthony.asserturo@hotmail.com A
Becky 555-7685 becky.algebrarum@gmail.com A
Bill 555-1675 bill.drowning@hotmail.com A
Broderick 555-0542 broderick.aliquotiens@yahoo.com R
Camilla 555-2912 camilla.infusarum@skynet.be R
Fabius 555-1234 fabius.undevicesimus@ucb.edu F
Julie 555-6699 julie.perscrutabor@skeeve.com F
Martin 555-6480 martin.codicibus@hotmail.com A
Samuel 555-3430 samuel.lanceolis@shu.edu A
Jean-Paul 555-2127 jeanpaul.campanorum@nyu.edu R
当前目录生成了awkvars.out文件
# cat awkvars.out
ARGC: 2
ARGIND: 1
ARGV: array, 2 elements
BINMODE: 0
CONVFMT: "%.6g"
ERRNO: ""
FIELDWIDTHS: ""
FILENAME: "mail-list"
FNR: 11
FPAT: "[^[:space:]]+"
FS: " "
IGNORECASE: 0
LINT: 0
NF: 4
NR: 11
OFMT: "%.6g"
OFS: " "
ORS: "\n"
RLENGTH: 0
RS: "\n"
RSTART: 0
RT: "\n"
SUBSEP: "\034"
TEXTDOMAIN: "messages"
2.3 常用内置变量
2.3.1 ARGV 和 ARGC
awk程序可用的命令行参数存储在名为ARGV的数组中。 ARGC是命令行参数的数量。ARGV数组索引从0到ARGC-1。
示例:
创建一个名为showargs.awk的文件
# cat showargs.awk
BEGIN {
printf "A=%d, B=%d\n", A, B
for (i = 0; i < ARGC; i++)
printf "\tARGV[%d] = %s\n", i, ARGV[i]
}
END { printf "A=%d, B=%d\n", A, B }
执行awk命令
# awk -v A=1 -f showargs.awk B=2 /dev/null
A=1, B=0
ARGV[0] = awk
ARGV[1] = B=2
ARGV[2] = /dev/null
A=1, B=2
在本例中,ARGV[0]为’awk’,ARGV[1]为’inventory shipped’,ARGV[2]为’mail list’,ARGC等于3。
ARGC 和 ARGV 是从C语言访问命令行参数的方法派生的。
2.3.2 FNR
当前文件中的当前记录号。 awk每次读取新记录时都会增加 FNR。 awk每次处理新的输入文件时将FNR重置为零。
2.3.3 NF
当前输入记录中的字段数。在上面示例的mail-list中,以空格为字段分隔符,字段数就是4,也就是4列。
2.3.4 NR
awk自程序开始执行以来,已处理了输入记录的数量。awk每次读取新记录时都会增加NR。
参考文档
https://www.gnu.org/software/gawk/manual/gawk.html