Home Map Index Search News Archives Links About LF
[Top bar]
[Bottom bar]
[Photo of the Author]
by Javier Palacios Bermejo

About the author:

Javier在西班牙大学致力于天文方面的哲学研究.在那里负责管理一些工作站.他所在部门的日常工作实在Unix系统上完成的.经过了一些初期问题和试验,他选择了slackware Linux. Linux显得比目前所有的其它Unix系统更好.

Content:

实例介绍

[Ilustration]

Abstract:

本文将介绍一些使用AWK的窍门。它并不是一份教材,但在其中将给出一些使用的例子。



最初,是在看了Guido Socher在linuxfocus上发表的几篇文章,才想写这篇文章。在Guido Socher的文章中有一篇是介绍文件查找和相关命令的,是我意识到并不是只有我一个人在使用命令行。很多时候漂亮的图形用户界面不能告诉我们事情是如何进行的(这是windows多年以来所延续的方法)。另一篇文章是关于规则表达式的。尽管在此文中没有过多的提及规则的表达式,你也要从awk以及其他的命令(如sed和grep)中了解到很多。

问题的关键是awk命令是否真的很有用。答案是肯定的。它将对普通用户的文本编辑有很大帮助,例如排版什么的。对于系统管理员AWK是一个非常重要的应用。随便看一下/var/yp/Makefile 或是看一下系统的初始化脚本,AWK在到处被使用着。

 

awk简介

我已记不起最初是什么时候听到有关AWK的消息。我的一个同事要处理由Cray大量的输出结果,而这个Cray上关于AWK的联机帮助很少,他说尽管它并不会用AWK但他觉得这正是他所需要的。
很长时间以后,我们再次开始我们的工作。一个同事利用下面的AWK命令从文件中提取所有行的第一列词:

awk '  '{print $1}'   file


这是不是很简单?这样一个简单的操作并不需要象在C语言中的复杂编程。一行AWK命令就解决了。

在我们知道了如何从文件中分离一列后,我们便可以做诸如更改文件名称的操作(在files_list加.new):

ls -1 pattern | awk '{print "mv "$1" "$1".new"}' | sh

... 另外,如果将sed和grep一起使用,那将会成为一个非常有用的工具.

  1. 在文件名内进行替换:
    ls -1 *old* | awk '{print "mv "$1" "$1}' | sed s/old/new/2 | sh
    (但有时这条命令也会发生错误,如在文件名为 file_old_and_old的时候。)
  2. 删除指定文件:(这可以使用 rm 本身来完成,打药指定别名 'rm -r')
    ls -l * | grep -v drwx | awk '{print "rm "$9}' | sh
    (并且这可能因为怪异的文件名和访问权限的限制失败.) 如果不是在你的home目录下请小心操作,我们可是在删除文件!
  3. 删除指定目录:
    ls -l | grep '^d' | awk '{print "rm -r "$9}' | sh
    (我认为这在任何情况下都将起作用,并且我们可以用 ls -p | grep /$ | wk '{print "rm -r "$1}'对他进行改进.)
    如果不是在你的home目录下请小心操作,我们可是在删除文件!

正如你所见到的,AWK在需要进行相同的计算时起作用。并且写一个AWK程序要比重复20此同样的操作更有意思。

确切的说,尽管我们说 awk-command,但awk并不是我们通常所说的那种命令.awk是一种可编程语言,AWK是一种在语法的很多方面与C语言相近的表成语言。是由awk解释程序进行解释的。

关于awk解释程序自身的语法:

# gawk --help
Usage: gawk [POSIX or GNU style options] -f progfile [--] file ...
        gawk [POSIX or GNU style options] [--] 'program' file ...
POSIX options:          GNU long options:
        -f progfile             --file=progfile
        -F fs                   --field-separator=fs
        -v var=val              --assign=var=val
        -m[fr] val
        -W compat               --compat
        -W copyleft             --copyleft
        -W copyright            --copyright
        -W help                 --help
        -W lint                 --lint
        -W lint-old             --lint-old
        -W posix                --posix
        -W re-interval          --re-interval
        -W source=program-text  --source=program-text
        -W traditional          --traditional
        -W usage                --usage
        -W version              --version

Report bugs to bug-gnu-utils@prep.ai.mit.edu,
with a Cc: to arnold@gnu.ai.mit.edu

你可以看到,命令可以用单引号引用在命令行运行,去掉单引号我们可以将命令写入一个文件,然后带参数-f运行。在命令行进行变量定义用到-v var=val,我们便可以增加程序的灵活性。大体上说来,AWK适合于管理表单。也就是把信息分到fields(字段)和record(记录)。

概略的说,Awk是面向表单管理的.也就是一些可以用字段和记录归类的信息.这样做的好处是纪录和字段的定义是比较灵活的。

AWK功能强大。被定义成对一行的纪录进行操作,但在这一点上并非十分严格。为了说明这一点,我们将看到下面的说明性的例子:

这样的一个程序,只需要用五分钟进行设计,五分钟写程序.

我也用awk实现其他功能(依据数据库中的信息自动生成页面),并且凭我所知道的,awk编程还可以做很多事。
尽情的发挥你的想象力吧。

 

一个问题:

 

(解决办法)

问题是awk需要一个很好的制表信息,没有空格,awk不能在定宽的列上工作。在我们自己应用awk进行输入时这并不是一个问题:选择一些特殊的字符进行分割,之后在进行修改。如果我们已经有了这样的输入表,这就会有一定的麻烦。例如下表:
1234  HD 13324  22:40:54 ....
1235  HD12223   22:43:12 ....

用awk处理这个问题很困难。不行的是这竟是一个经常出现的问题。Inputs like this sometimes are mandatory. Besides, this is quite common because data input is not homogeneous whatsoever. 如果我们只有一列存在这样的特征,就有办法解决.(如果那位知道如何简便的管理一个表的多列,请告诉我!).
一旦我们必然面对上面相识的情况.第二个字段是一个名字其中包括了不定个数的空格。鉴于这是经常出现的,我们必须用它的最后一列进行挑选。

忽然我发现我所要处理的是最后一列,并且Awk知道当前纪录中有多少个列.因此这样就能够访问最后一列.(有时是 $9, 有时是 $11, 但总是 NF). 这样的描述结果:
{
  printf $NF
  $NF = ""
  printf " "$0"\n"
}


折旧提供了一个等同于输出的输入.这只不过是把最后一列转移到第一的位置。显然这对于倒数第三个字段也是很容易的,或是对于在定值字段后面的一个字段也是方便的。
应用这种把最后一列放到第一列的位置的方法,我们就可以解决所有问题.
运用你的想象力就可以想出办法.

 

更深层次的AWK

 

处理符合条件的行

到此为止,所有的例子都是处理输入文件的所有行的。但正如手册中所说的,AWK是可以只处理部分行的。只有在满足条件的时候,才进行执行。匹配条件可以非常灵活,用一个简单的逻辑操作符所组成的条件组的标准表达式来检查内容中的字段。

 

作为可编程语言的AWK

争相其它编程语言一样,awk实现了所有的重要的流式控制结构,同时利用操作符和预定义的函数来处理数字和字符串。其语法与C语言相近.

AWK当然也可通过关键字function来加入用户定义的函数。除了一般的符号变量外,awk也可以操作数组。

 

引用库

像在所有的语言中一样,存在很多常用的函数需要在代码中经常复制和粘贴。这正是为什么引入库的概念。对于GNU的awk,可以在程序中引用库文件。但这并不在本文的讨论范围之内。

 

结论

当然,awk其它一些可以用作相同目的的工具一样强大,但是它的最大优点是可以在很短的时间内制作出小程序来解决我们的问题。

AWK非常适合以下目的的需求:需要从数据中一行一行的读出内容,并对字符和格式进行操作。

象/etc/passwd 这样的文件就可以用awk对他进行格式处理。对于这样的操作awk是再合适不过的了。

当然在这方面并不是只有AWK。Perl也是一个非常有力的竞争者,但还是值得去了解一些AWK的技巧。

 

附加信息

这只不过是一些很基础的命令,也没有很好的整理,你可以在更广泛的阅读中找到更多的东西。

通常在所有的unix书中都提及到awk,但很少有书中仔细的对其进行介绍。所以我们最好浏览所有我们手头的书,你永远不知道省么时候可以找到一些有用的东西。


Webpages maintained by the LinuxFocus Editor team
© Javier Palacios Bermejo
LinuxFocus 1999
Translation information:
es -> -- Javier Palacios Bermejo
es -> en Javier Palacios Bermejo,Ruben Sotillo, Manuel Rodriguez
en -> chinese wang zhuohao

1999-11-02, generated by lfparser version 0.8