Input
回顾一下,awk的使用方法awk 'program ' data
所以data对于awk也是很重要的一部分。
- 如果没有文件作为Awk的输入,它将根据标准输入读取。
egrep是一个可以对输入的数据进行匹配选择的程序,他的速度要快于awk
egrep 'Asia' countries : awk 'program'
Input Separators输入分隔符
默认FS=”“,也就是会按照blanks and/or tabs 进行分隔。所以会忽略多个空格及tab
FS也可以通过正则表达式进行设置,AWK参考书中给出了例子
BEGIN { FS = ",[ \t]*|[ \t]+"}
注意 FS=”[ ]”将分隔符设置为单个blank
分隔符也可以通过-F参数进行设置,
awk -F', [ \t]*| [ \t]+' 'program'
Multiline Records读取多行记录
行分隔符由RS的值决定,默认是”“,分隔符是:一个或者多个空行分隔
BEGIN { RS = ""; FS = "\n" }
设置记录按照一个或者多个空行分隔,同时列在单独的一个行。
一个记录最多可以有3000个字符。更多设置见后。
The getline Function
getline会读取下一行记录,并进行NF,NR,FNR的设置
返回值为0表示EOF文件结束,为1表示正确读取了一条数据,-1表示错误读取,比如打开文件失败。
getline x
读取下一个记录存储在变量x中,同时设置NR,FNR,不设置NFgetline < "file"
“file”作为当前的输入,不影响NR,FNR,但是设置列NFgetline x <"file"
没有任何分隔行为,所以不影响NF,NR,FNR的值#include "filename"
引用文件。编译时会找到filename文件,替换这句话读取
#好像是include的实现文档?
# include - replace #include "f" by contents of file f
/^#include/ {
gsub(/"/, "", $2)
while (getline x <$2 > 0)
print x
next
}
{ print }
- getline function
函数 | Sets |
---|---|
getline | $0, NF, NR, FNR |
getline var | var, NR, FNR |
getline | $0, NF |
getline var | var |
cmd | getline | $0,NF |
cmd | getline var | var |
可以将输出直接通过管道导入到getline中
while ("who" | getline) n++
执行who这个命令,然后输出到getline注意如果getline没有读取成功会出错
- 危险用法:
while(getline< "file")…
访问file出问题时,getline返回值为-1,会陷入死循环
- 安全用法:
while (getline <"file" > 0) …
加上判断语句,只有getline返回值大于0即为1的时候才可以执行。(1>0)
- 危险用法:
next 和getline
- 在awk中,如果调用next,那么next之后的命令就都不执行了。此行文本的处理到此结束,开始读取下一条记录并操作。
- 与next相似,getline也是读取下一行数据。但是与next不同的是,next读取下一行之后,把控制权交给了awk脚本的顶部。但是getline却没有改变脚本的控制,读取下一行之后,继续运行当前的awk脚本。getline执行之后,会覆盖$0的内容。
Command-Line Variable Assignments命令行变量赋值
awk 'program' f1 f2 …
awk -f progfile f1 f2 …
awk -Fsep 'program' f1 f2
awk -Fsep -f progfile f1 f2 …
f1,f2…在命令行中通常是表示文件名的参数。
如果有一个部分是var=text ,这就是将text付给var。这个操作可以在读取file前后执行。
Command-Line Arguments命令行赋值
ARGC和ARGV[]
ARGC和ARGV[]事awk提供的内置变量。
通过命令行赋给awk的数值都存储在一个内置的数组ARGV中
(ARGC命令行参数个数,ARGV命令行参数数组)
ARGC的数值超过了参数的值。比如
awk -f progfile a v=1 b
ARGC=4
ARGV[0]=”awk”;ARGV[1]=”a”;ARGV[2]=”v=1”;ARGV[3]=”b”
因为命令 awk 被算成了第0个参数。正如在C语言中一样。
命令行上的 “-f”,”-F”,” -vx”选项及参数,或程序部分 ‘{ print 1, 2}’ 都不会列入 ARGC 及 ARGV[ ] 中。
输出ARGV[]内容:
BEGIN { for (i = 1; i < ARGC; i++) printf "%s ", ARGV[i] printf "\n" }
ARGV中的参数可以被修改或添加; ARGC可以被更改。
当每个输入文件结束时,awk将ARGV的下一个非空元素(通过ARGC-1的当前值)视为下一个输入文件的名称。 因此,将ARGV的元素设置为null意味着它不会被视为输入文件。 “-” 可用作标准输入。awk 利用 ARGC 来判断应打开的数据文件个数
没太能理解意思,先mark一下,日后再补充参考:读取命令行上的参数
使用者可强行改变 ARGC;当 ARGC 的值被使用者设为 1 时,awk将被蒙骗,误以为命令行上并无数据文件文件名,故不会以 ARGV[1],ARGV[2],…为文件名来打开文件读取数据;但在程序中仍可通过ARGV[1],ARGV[2],…来取得命令行上的数据。
awk实现seq打印整数序列
写好seq之后可以用awk进行调用
# seq - print sequences of integers
# input: arguments q, p q, or p q r; q >= p; r > 0
# output: integers 1 to q, p to q, or p to q in steps of r
BEGIN {
if (ARGC == 2)
for (i = 1; i <= ARGV[1]; i++)
print i
else if (ARGC == 3)
for (i = ARGV[1]; i <= ARGV[2]; i++)
print i
else if (ARGC == 4)
for (i = ARGV[1]; i <= ARGV[2]; i += ARGV[3])
print i
}
以下三种方式都可以生成1-10的整数序列
awk -f seq 10
awk -f seq 1 10
awk -f seq 1 10 1