在学习awk时我们常会碰到awk,nawk,oawk,gawk,mawk。这可真是让人有点糊涂了。在网上找到一些关于这几个的资料。
awk:a w k是一种程序语言,对文档资料的处理具有很强的功能。awk 名称是由它三个最初设计者的姓氏的第一个字母而命名的: Alfred V. Aho、Peter J. We i n b e rg e r、Brian W. Kernighan。
a w k最初在1 9 7 7年完成。1 9 8 5年发表了一个新版本的a w k,它的功能比旧版本增强了不少。a w k 能够用很短的程序对文档里的资料做修改、比较、提取、打印等处理。如果使用C 或P a s c a l 等语言编写程序完成上述的任务会十分不方便而且很花费时间,所写的程序也会很大。
nawk: 在 20 世纪 80 年代中期,对 AWK 语言进行了更新,并不同程度地使用一种称为 NAWK (New AWK)
的增强版本对其进行了替换。许多系统中仍然存在着旧的 AWK 解释器,但通常将其安装为 oawk (Old AWK) 命令,而 NAWK
解释器则安装为主要的 awk 命令,也可以使用 nawk 命令。Dr. Kernighan 仍然在对 NAWK 进行维护,与 GAWK
一样,它也是开放源代码的,并且可以免费获得。
gawk: 是 GNU Project 的 AWK 解释器的开放源代码实现。尽管早期的 GAWK 发行版是旧的 AWK 的替代程序,但不断地对其进行了更新,以包含 NAWK 的特性。
mawk:Mawk 是 AWK 编程语言的解释器。AWK 语言在多媒体数据文件以及文本的检索和处理,算法的原型设计和试验都有广泛的使用。Mawk带给awk新的概念,它实现了在《The AWK Programming Language》(Aho,
Kernighan and Weinberger, The AWK Programming Language, Addison-Wesley
Publishing, 1988.被认为是 AWK 手册。)中定义的 AWK 语言。Mawk 遵循 POSIX 1003.2 (草案 11.3)定义的 AWK 语言,包含了一些没有在AWK 手册中提到的特色,同时 mawk 提供一小部分扩展。
目前我们比较倾向于使用gawk和awk。
下面就根据我的理解对awk作一些简单的介绍。
一.awk三种调用方法,这是程式化的东西,没什么好说的。
1)命令行方式awk [-F field-separator]'commands' input-file(s)
这里的commands是真正的awk命令。-F是域分隔符,可选。
2)第二种方法是将所有的awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行以便通过键入脚本名称来调用它。
3)将所有的awk命令插入一个单独的文件,然后调用
awk -f awk-script-file input-file(s)
二: 以前学过java下的正则表达式,就感觉正则表达式在文本处理方面已是非常强大的,但是学了awk之后发现awk和正则表达式结合起来,功能更加强大。下面是一个例子,虽然完成的功能很一般,但是可以看到awk和正则表达式的强大了。
1. 首先,我有一个文件test.c如下:
# #include
# #define M 5
# #define N 3
#
# int k = 0;
# int check_over(int a[]){
# int i;
# for(i=0; i# if(a[i] == 1)
break;
}
return M-N-i;
}
现在我要将没一行前边多余的那个#去掉,并将新文件存方在test2.c中。那么我就可以用这样一条语句:
awk '{if($1 == "#") print substr($0,2);else print $0}' test.c | cat > test2.c
或者这样的语句:
awk '{if($0 ~/#.*/) print substr($0, 2); else print $0}' test.c | cat > test2.c
三: 再比如我想要从/etc/passwd文件中读出用户的注册名和用户名,首先我们知道passwd文件中存放了用户的关键信息。系统中每一个合法用户的帐号对应了该文件的一行。每一行的用户记录的各个数据段用:隔开。分别包括注册名,口令,用户标识号,组标识号,用户名,用户主目录,命令解释器shell。那么我们对应的awk脚本文件就可以这样写:文件名是passwd.awk
#!/usr/bin/awk -f
BEGIN{
FS=":"; #定义了分隔符
}
{print $1,"\t",$5} #打印每一行的第一和第五字段的内容
执行时直接输入./passwd.awk /etc/passwd就ok了。
四: 正则表达式中的‘?’的问题。?表示他前边的字符出现0-1次。比较和‘*’的不同,‘*’表示他前边的字符出现0-n次。比如下边这个例子:
along@along-laptop:~/code/shell$ cat test
xyz
yz
xz
xyyyz
along@along-laptop:~/code/shell$ awk '$0 ~/xy?z/{print $0}' test
xyz
xz
along@along-laptop:~/code/shell$ awk '$0 ~/xy*z/{print $0}' test
xyz
xz
xyyyz
五:将awk的输出重定向到一个文件。
along@along-laptop:~/code/shell$ cat hang
1.adf
2.skdf
3.adslfk
4adsf
adflj
sdj
我现在想到的方法有:
awk '$0~/^[0-9]/{print $1}' hang | tee test_out
awk '$0~/^[0-9]/{print $1>"test_out"}' hang
awk '$0~/^[0-9]/{print $1}' hang > test_out
六:实现简单的交互式shell
现在我想要用awk实现交互式shell,我们举个简单的例子来看:
从键盘接收一个数字,然后分别打印出这个数字,和这个数字的阶乘。
我的awk脚本文件是这样写的(文件名为jc.awk):
#!/usr/bin/awk -f
BEGIN {
print "input a number:";
getline number; #从键盘接收数据到number
print "your inout is:" number; #打印出接收到的内容
if(number == 0)
fact=1;
else
fact=number;
for(i=number-1; i>=1; i--) #计算number的阶乘
fact*=i;
print number"!="fact;
}
赋予jc.awk以执行权限,在终端下直接输入./jc.awk即可。执行结果:
along@along-laptop:~/code/shell$ ./jc.awk
input a number:
4
your inout is:4
4!=24
在命令行下实现简单的交互式shell:
awk 'BEGIN{print "input a number:";getline d;print "your input is:"d}'
阅读(756) | 评论(0) | 转发(0) |