分类: 系统运维
2011-08-12 10:35:45
记录
awk把每一个以换行符结束的行称为一个记录。
记录分隔符:默认的输入和输出的分隔符都是回车,保存在内建变量ORS和RS中。
$0变量:它指的是整条记录。如$ awk '{print $0}' test将输出test文件中的所有记录。
变量NR:一个计数器,每处理完一条记录,NR的值就增加1。如$ awk '{print NR,$0}' test将输出test文件中所有记录,并在记录前显示记录号。
域
记录中每个单词称做“域”,默认情况下以空格或tab分隔。awk可跟踪域的个数,并在内建变量NF中保存该值。如$ awk '{print $1,$3}' test将打印test文件中第一和第三个以空格分开的列(域)。
域分隔符
内建变量FS保存输入域分隔符的值,默认是空格或tab。我们可以通过-F命令行选项修改FS的值。如$ awk -F: '{print $1,$5}' test将打印以冒号为分隔符的第一,第五列的内容。
符写成放到方括号中,如$awk -F'[:\t]' '{print $1,$3}' test,表示以空格、冒号和tab作为分隔符。
输出域的分隔符默认是一个空格,保存在OFS中。如$ awk -F: '{print $1,$5}' test,$1和$5间的逗号就是OFS的值。
笔记:
[czmmiao@czmmiao txt]$ cat employees2
打印出以“:”为域分隔符中第4域小于30000的记录
Marry Adams 5436
打印出以“:”为域分隔符中第4域小于30000的记录中的第1域和第二域
Tom Jones:4432:5/12/66:543354
打印出以“:”为域分隔符中第4域大于350000 且小于 550000的记录
Tom Jones 4432
打印出以“:”为域分隔符中第4域大于350000 且小于 550000的第1域和第2域
[czmmiao@czmmiao txt]$ awk -F: '($2 + $4) <550000 ' employees2Billy Black:1683:9/23/44:336500
打印出以“:”为域分隔符中第2域和第4域之和小于550000的记录
[czmmiao@czmmiao txt]$ awk -F: '($2 + $4) <545000 ' employees2
Billy Black:1683:9/23/44:336500
打印出以“:”为域分隔符中第2域和第4域之和小于545000的记录
Billy Black:1683:9/23/44:336500
打印出以“:”为域分隔符中第2域和第4域之和的平均值小于270000的记录
[czmmiao@czmmiao txt]awk -F: '$1~/Tom/{wage = $2 + $4;print wage}' employees2
547786
应用wage这个自定义变量,打印出以“:”为域分隔符且第一域包含“Tom"关键字的第2域和第4域之和
Tom Jones 1111 5/12/66 543354
找出以“:”为域分隔符且第二域等于4432的记录,并把第2域赋值为1111进行打印
[czmmiao@czmmiao txt]$ awk -F: '$1 == "Sally Chang"{print NR,$1,$2,$NF}' employees2找出以“:”为域分隔符且第二域等于Sally Chang的记录,打印出记录行号,第1域,第2域和最后一个域。这里注意,如果不加“ ”那么,awk会匹配空字符串结果如下
[root@czmmiao txt]# awk -F: '$1==Sally{print $1,$2,$NF}' employees2
[root@czmmiao txt]#
Tom Jones 4432 5/12/66
设定以“:”为域分隔符,制表符(\t)为,两个回车为记录分隔符,打印第1域,第2域,第3域
[czmmiao@czmmiao txt]$ awk 'BEGIN{print "MAKE YEAR"}'
MAKE YEAR
打印“MAKE YEAR"跟在BEGIN后的语句先执行,即使没有输入文件,awk仍然执行BEGIN后的语句
The number of records is 4
打印“The number of records is "记录号,跟在END后的语句最后执行。(下例体现得更明显。。。。。)
以“:”为域分隔符,查找第2域大于2000的记录,打印第1域,第2域并重定向到当前目录下的passing_file中
[czmmiao@czmmiao txt]$ awk 'BEGIN{"date" |getline d;print d}'
执行"date"命令,利用getline函数将执行结果传入参数d,打印参数d
执行"date"命令,利用getline函数将执行结果传入参数d,split函数充d中生存名称为mon的数组,打印数组中的第二个元素
执行"ls"命令,把输出结果发送给getline。每循环一次,getline函数得到一个传入值,并一一打印
打印输出“What is your name?" 利用getline函数从终端接收输入,并传送给name变量,直到用户输入回车为止,如果第一域匹配employees2中的记录。
打印“Found ",name变量,"on line" ,行号。
打印“See ya, ”,name变量
以上是传入name变量的值存在于employees2中的情况
[czmmiao@czmmiao txt]$ awk 'BEGIN{printf "What is your name?" ;\不存在于employees2中的情况
awk逐行读取文件直至文件结束,然后打印出1c的值,也就是文件行数。注意:如果文件不存在getline的将是-1,如果读到文件末尾返回值为0,读到一行时返回值为1。
上例中,第一条命令getline逐行读取文件,每次的返回值都为1,故循环为真,并且每次1c都+1。直到文件末尾,返回为0时,退出循环,1c 最后一次+ 1。打印1c值
第2条命令,由于不存在/etc/passwd1文件,getline返回值为-1直接退出循环,1c 进行+1后打印
第3条命令,由于不存在/etc/passwd1文件,getline返回值为-1,但是由于循环为真,故进行死循环。中断后,查询出该命令错误。