Chinaunix首页 | 论坛 | 博客
  • 博客访问: 28447
  • 博文数量: 109
  • 博客积分: 495
  • 博客等级: 大尉
  • 技术积分: 1055
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-23 14:12
文章分类

全部博文(109)

文章存档

2012年(21)

2011年(88)

我的朋友
最近访客

分类: 系统运维

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

Tom Jones:4432:5/12/66:543354
Marry Adams:5436:11/4/63:28765
Sally Chang:1655:7/22/54:650000
Billy Black:1683:9/23/44:336500

[czmmiao@czmmiao txt]$ awk -F: '$4 < 30000' employees2
Marry Adams:5436:11/4/63:28765

打印出以“:”为域分隔符中第4域小于30000的记录

[czmmiao@czmmiao txt]$ awk -F: '$4 < 30000 {print$1,$2}' employees2

Marry Adams 5436

打印出以“:”为域分隔符中第4域小于30000的记录中的第1域和第二域


[czmmiao@czmmiao txt]$ awk -F: '$4 > 350000 && $4 < 550000' employees2

Tom Jones:4432:5/12/66:543354

打印出以“:”为域分隔符中第4域大于350000 且小于 550000的记录

[czmmiao@czmmiao txt]$ awk -F: '$4 > 350000 && $4 < 550000 {print $1,$2}' employees2

Tom Jones 4432

打印出以“:”为域分隔符中第4域大于350000 且小于 550000的第1域和第2域

[czmmiao@czmmiao txt]$ awk -F: '($2 + $4) <550000 ' employees2
Tom Jones:4432:5/12/66:543354
Marry Adams:5436:11/4/63:28765

Billy Black:1683:9/23/44:336500

打印出以“:”为域分隔符中第2域和第4域之和小于550000的记录

[czmmiao@czmmiao txt]$ awk -F: '($2 + $4) <545000 ' employees2

Marry Adams:5436:11/4/63:28765

Billy Black:1683:9/23/44:336500

打印出以“:”为域分隔符中第2域和第4域之和小于545000的记录

[czmmiao@czmmiao txt]$ awk -F: '($2 + $4)/2<270000' employees2
Marry Adams:5436:11/4/63:28765

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域之和

$ awk -F: '$2 == 4432 { $2 = 1111;print}' employees2

Tom Jones 1111 5/12/66 543354

找出以“:”为域分隔符且第二域等于4432的记录,并把第2域赋值为1111进行打印

[czmmiao@czmmiao txt]$ awk -F: '$1 == "Sally Chang"{print NR,$1,$2,$NF}' employees2
3 Sally Chang 1655 650000

找出以“:”为域分隔符且第二域等于Sally Chang的记录,打印出记录行号,第1域,第2域和最后一个域。这里注意,如果不加“ ”那么,awk会匹配空字符串结果如下

[root@czmmiao txt]# awk -F: '$1==Sally{print $1,$2,$NF}' employees2 

[root@czmmiao txt]# 

[czmmiao@czmmiao txt]$ awk -F: '{IGNORECASE=1};\
> $1 == "sally chang"{print NR,$1,$2,$NF}' employees2
3 Sally Chang 1655 650000
找出以“:”为域分隔符,打印记录中包含"sally chang"的记录号,第1域,第2域和最后一域。其中IGNORECASE=1参数表示忽略大小写,这样"sally chang" 能够匹配"Sally Chang"

[czmmiao@czmmiao txt]$ awk 'BEGIN{FS=":";OFS="\t";ORS="\n\n"}{print $1,$2,$3}' employees2

Tom Jones 4432 5/12/66


Marry Adams 5436 11/4/63

Sally Chang 1655 7/22/54

Billy Black 1683 9/23/44


设定以“:”为域分隔符,制表符(\t)为,两个回车为记录分隔符,打印第1域,第2域,第3域

[czmmiao@czmmiao txt]$ awk 'BEGIN{print "MAKE YEAR"}'

MAKE YEAR


打印“MAKE YEAR"跟在BEGIN后的语句先执行,即使没有输入文件,awk仍然执行BEGIN后的语句

[czmmiao@czmmiao txt]$ awk 'END{print "The number of records is "NR}' employees2

The number of records is 4

打印“The number of records is "记录号,跟在END后的语句最后执行。(下例体现得更明显。。。。。)

[czmmiao@czmmiao txt]$ awk '/Marry/{count++}END{print "Marry was found " count " times."}' employees2
Marry was found 1 times.

查找包含Marry的字段,每查找到一个自定义变量+1最后执行打印“Marry was found",变量count, "times."
[czmmiao@czmmiao txt]$ awk -F: '$2 > 2000 {print $1,$2 > "passing_file"}' employees2
[czmmiao@czmmiao txt]$ ls
awkfile datafile1 employees2 info passing_file
datafile employees facts newfile
[czmmiao@czmmiao txt]$ cat passing_file
Tom Jones 4432
Marry Adams 5436

以“:”为域分隔符,查找第2域大于2000的记录,打印第1域,第2域并重定向到当前目录下的passing_file中

[czmmiao@czmmiao txt]$ awk 'BEGIN{"date" |getline d;print d}' 

2010年 12月 16日 星期四 22:55:19 CST

执行"date"命令,利用getline函数将执行结果传入参数d,打印参数d

[czmmiao@czmmiao txt]$ awk 'BEGIN{"date" |getline d;split(d,mon);print mon[2]}' employees2
12月

执行"date"命令,利用getline函数将执行结果传入参数d,split函数充d中生存名称为mon的数组,打印数组中的第二个元素

[czmmiao@czmmiao txt]$ awk 'BEGIN{while("ls"|getline) print}'
awkfile
datafile
datafile1
employees
employees2
facts
info
newfile
passing_file

执行"ls"命令,把输出结果发送给getline。每循环一次,getline函数得到一个传入值,并一一打印

[czmmiao@czmmiao txt]$ awk 'BEGIN{printf "What is your name?" ;\
getline name < "/dev/tty"}\
$1 ~ name {print "Found " name " on line ",NR "."}\
END{print "See ya, " name "."}' employees2
What is your name?Tom
Found Tom on line 1.
See ya, Tom.

打印输出“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?" ;\
getline name < "/dev/tty"}\
$1 ~ name {print "Found " name " on line ",NR "."}\
END{print "See ya, " name "."}' employees2
What is your name?czmmiao
See ya, czmmiao.

不存在于employees2中的情况

[czmmiao@czmmiao txt]$ awk 'BEGIN{while(getline < "/etc/passwd" >0)1c++;print 1c}'
141
[czmmiao@czmmiao txt]$ awk 'BEGIN{while(getline < "/etc/passwd1" >0)1c++;print 1c}'
1
[czmmiao@czmmiao txt]$ awk 'BEGIN{while(getline < "/etc/passwd1" )1c++;print 1c}'
^C
[czmmiao@czmmiao txt]$ echo $?
130

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,但是由于循环为真,故进行死循环。中断后,查询出该命令错误。

阅读(400) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~