Unix awk命令(1~3) — awk命令

zz http://blog.csdn.net/ShowMan/archive/2009/07/14/4348208.aspx

 

     awk语言的最基本功能是在文件或字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作,完整的awk脚本通常用来格式化文本文件中的信息

调用awk :
   第一种,命令行方式,如:awk 
[-F field-separator] 
'commands'
 input-file(s)
        
这里commands是真正的awk命令,[-F域分隔符]是可选的,awk默认使用空格分隔,因此如果要浏览域间有空格的文本,不必指定这个选项,但如
果浏览如passwd文件,此文件各域使用冒号作为分隔符,则必须使用-F选项:   awk -F : 'commands' input-file
   第二种,将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它
   第三种,将所有awk命令插入一个单独文件,然后调用: awk
 -f
 awk-script-file
 input-file
         -f选项指明在文件awk-script-file的awk脚本,input-file是使用awk进行浏览的文件名

awk脚本

:
    awk脚本由各种操作和模式组成,根据分隔符(-F选项),默认为空格,读取的内容依次放置到对应的域中,一行一行记录读取,直到文件尾
    模式和动作
:任何awk语句都是由模式和动作组成,在一个awk脚本中可能有许多语句。模式部分

决定动作语句何时触发及触发事件。动作

即对数据进行的操作,如果省去模式部分,动作将时刻保持执行状态
    模式可以是任何条件语句或复合语句或正则表达式,模式包含两个特殊字段BEGIN和END,使用BEGIN语句设置计数和打印头,BEGIN语句

使用在任何文本浏览动作之前,之后文本浏览动作依据输入文件开始执行;END语句

用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志,有动作必须使用{}括起来
    实际动作在大括号{}内指明,常用来做打印动作,但是还有更长的代码如if和循环looping语句及循环退出等,如果不指明采取什么动作,awk默认打印出所有浏览出的记录

域和记录

:
    awk执行时,其浏览标记为$1,$2...$n,这种方法称为域标记
.使用$1,$3表示参照第1和第3域,注意这里使用逗号分隔域,使用$0表示使用所有域
    例:awk '{print $0}' temp.txt > sav.txt   表示打印所有域并把结果重定向到sav.txt中
      awk '{print $0}' temp.txt|tee sav.txt  和上例相似,不同的是将在屏幕上显示出来
      awk '{print $1,$4}' temp.txt           只打印出第1和第4域
      awk 'BEGIN {print "NAME  GRADE/n-------------"} {print $1"/t"$4}' temp.txt 
        表示打信息头,即输入的内容的第一行前加上"NAME  GRADE/n-------------",同时内容以tab分开
      awk 'BEGIN {print "being"} {print $1} END {print "end"}' temp 同时打印信息头和信息尾

条件操作符

:
    <、<=、==、!=、>=、~匹配正则表达式、!~不匹配正则表达式
    匹配
:awk '{if ($4~/ASIMA/) print $0}' temp 表示如果第四个域包含ASIMA,就打印整条
        awk '$0 ~ /ASIMA/' temp 表示只要整条包含ASIMA就打印出来
    精确匹配
:awk '$3=="48" {print $0}' temp    只打印第3域等于"48"的记录
    不匹配
:  awk '$0 !~ /ASIMA/' temp      打印整条不包含ASIMA的记录
    不等于
:  awk '$1 != "asima"' temp
    小于
:    awk '{if ($1<$2) print $1 "is smaller"}' temp
    设置大小写
: awk '/[Gg]reen/' temp      打印整条包含Green,或者green的记录
    任意字符
: awk '$1 ~/^...a/' temp    打印第1域中第四个字符是a的记录,^行首,.任意字符
    或关系匹配
: awk '$0~/(abc)|(efg)/' temp   使用|时,语句需要括起来
    AND与关系
:  awk '{if ( $1=="a" && $2=="b" ) print $0}' temp
    OR或关系
:   awk '{if ($1=="a" || $1=="b") print $0}' temp

awk内置变量

:
    ARGC   命令行参数个数    AGRV   命令行参数排列      ENVIRON   支持队列中系统环境变量的使用
    FILENAME   awk浏览的文件名   FNR   浏览文件的记录数   FS   设置输入域分隔符,同- F选项
    NF   浏览记录的域个数   NR   已读的记录数    OFS   输出域分隔符
    ORS  输出记录分隔符     RS   控制记录分隔符
    例:  awk 'END {print NR}' temp    在最后打印已读记录条数
         awk '{print NF,NR,$0} END {print FILENAME}' temp
         awk '{if (NR>0 && $4~/Brown/) print $0}' temp  至少存在一条记录且包含Brown
    NF的另一用法
:  echo $PWD | awk -F/ '{print $NF}'   显示当前目录名

awk操作符

:
    在awk中使用操作符,基本表达式可以划分成数字型
字符串型
变量型

数组元素

    设置输入域到变量名
:
       awk '{name=$1;six=$3; if (six=="man") print name " is " six}' temp
    域值比较操作
:
       awk 'BEGIN {BASE="27"} {if ($4<BASE) print $0}' temp
    修改数值域取值
:(原输入文件不会被改变)
       awk '{if ($1=="asima") $6=$6-1;print $1,$6,$7}' temp
    修改文本域
:
       awk '{if ($1=="asima) ($1=="desc");print $1}' temp
    只显示修改记录
:(只显示所需要的,区别上一条命令,注意{}
)
       awk '{if ($1=="asima) {$1=="desc";print$1}}' temp
    创建新的输出域
:
       awk '{$4=$3-$2; print $4}' temp
    统计列值
:
       awk '(tot+=$3);END {print tot}' temp           会显示每列的内容
       awk '{(tot+=$3)};END {print tot}' temp         只显示最后的结果
    文件长度相加
:
       ls -l|awk '/^[^d]/ {print $9"/t"$5} {tot+=$5} END{print "totKB:" tot}'
    只列出文件名
:
       ls -l|awk '{print $9}'     常规情况文件名是第9域

awk内置字符串函数

:
    gsub(r,s)
           在整个$0中用s替代r
       awk 'gsub(/name/,"xingming") {print $0}' temp
    gsub(r,s,t)
         在整个t中用s替代r
    index(s,t)
          返回s中字符串t的第一位置
       awk 'BEGIN {print index("Sunny","ny")}' temp     返回4
    length(s)
           返回s的长度
    match(s,r)
          测试s是否包含匹配r的字符串
       awk '$1=="J.Lulu" {print match($1,"u")}' temp    返回4
    split(s,a,fs)
       在fs上将s分成序列a
       awk 'BEGIN {print split("12#345#6789",myarray,"#")"'
       返回3,同时myarray[1]="12", myarray[2]="345", myarray[3]="6789"
    sprint(fmt,exp)
     返回经fmt格式化后的exp
    sub(r,s)
            从$0中最左边最长的子串中用s代替r(只更换第一遇到的匹配字符串)
    substr(s,p)
         返回字符串s中从p开始的后缀部分
    substr(s,p,n)
       返回字符串s中

p
开始长度为n
的后缀部分

printf函数的使用

:
    字符转换
: echo "65" |awk '{printf "%c/n",$0}'    输出A
             awk 'BEGIN {printf "%f/n",999}'        输出999.000000
    格式化输出
:awk '{printf "%-15s %s/n",$1,$3}' temp 将第一个域全部左对齐显示

其他awk用法

:
    向一行awk命令传值
:
        awk '{if ($5<AGE) print $0}' AGE=10 temp
        who | awk '{if ($1==user) print $1 " are in " $2 ' user=$LOGNAME 使用环境变量
    awk脚本命令
:
        开头使用 !/bin/awk -f  ,如果没有这句话自含脚本将不能执行,例子:

  1. !/bin/awk -f
  2. # all comment lines must start with a hash '#'
  3. # name: student_tot.awk
  4. # to call: student_tot.awk grade.txt
  5. # prints total and average of club student points
  6.  
  7. # print a header first
  8. BEGIN
  9. {
  10.     print "Student    Date   Member No.  Grade  Age  Points  Max"
  11.     print "Name       Joined                         Gained  Point Available"
  12.     print "================================================================="
  13. }
  14. # let's add the scores of points gained
  15. (tot+=$6);
  16. # finished processing now let's print the total and average point
  17. END
  18. {
  19.     print "Club student total points :" tot
  20.     print "Average Club Student points :" tot/N
  21. }

awk数组

:
    awk的循环基本结构    For (element in array) print array[element]
    awk 'BEGIN {record="123#456#789";split(record,myarray,"#")} 
         END { for (i in myarray) {print myarray[i]} }

 

Unix awk命令(1) -- awk命令介绍

转载 http://www.myfaq.com.cn/2005September/2005-09-13/194026.html

什么是awk? 


可能对UNIX比较熟悉,但你可能对awk很陌生,这一点也不奇怪,的确,与其优秀的功能相比,awk还远没达到它应有的知名度。awk是什么?与其它大
多数UNIX命令不同的是,从名字上看,我们不可能知道awk的功能:它既不是具有独立意义的英文单词,也不是几个相关单词的缩写。事实上,awk是三个
人名的缩写,他们是:Aho、(Peter)Weinberg和(Brain)Kernighan。正是这三个人创造了awk---一个优秀的样式扫描与
处理工具。 

AWK的功能是什么?与sed和grep很相似,awk是一种样式扫描与处理工具。但其功能却大大强于sed和grep。
awk提供了极其强大的功能:它几乎可以完成grep和sed所能完成的全部工作,同时,它还可以可以进行样式装入、流控制、数学运算符、进程控制语句甚
至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上,awk的确拥有自己的语言:awk程序设计语言,awk的三位创建者
已将它正式定义为:样式扫描和处理语言。 

为什么使用awk? 

即使如此,你也许仍然会问,我为什么要使用awk? 

使
用awk的第一个理由是基于文本的样式扫描和处理是我们经常做的工作,awk所做的工作有些象数据库,但与数据库不同的是,它处理的是文本文件,这些文件
没有专门的存储格式,普通的人们就能编辑、阅读、理解和处理它们。而数据库文件往往具有特殊的存储格式,这使得它们必须用数据库处理程序来处理它们。既然
这种类似于数据库的处理工作我们经常会遇到,我们就应当找到处理它们的简便易行的方法,UNIX有很多这方面的工具,例如sed 、grep、sort以
及find等等,awk是其中十分优秀的一种。 

使用awk的第二个理由是awk是一个简单的工具,当然这是相对于其强大的功能来说的。
的确,UNIX有许多优秀的工具,例如UNIX天然的开发工具C语言及其延续C++就非常的优秀。但相对于它们来说,awk完成同样的功能要方便和简捷得
多。这首先是因为awk提供了适应多种需要的解决方案:从解决简单问题的awk命令行到复杂而精巧的awk程序设计语言,这样做的好处是,你可以不必用复
杂的方法去解决本来很简单的问题。例如,你可以用一个命令行解决简单的问题,而C不行,即使一个再简单的程序,C语言也必须经过编写、编译的全过程。其
次,awk本身是解释执行的,这就使得awk程序不必经过编译的过程,同时,这也使得它与shell script程序能够很好的契合。最后,awk本身
较C语言简单,虽然awk吸收了C语言很多优秀的成分,熟悉C语言会对学习awk有很大的帮助,但awk本身不须要会使用C语言——一种功能强大但需要大
量时间学习才能掌握其技巧的开发工具。 

使用awk的第三个理由是awk是一个容易获得的工具。与C和C++语言不同,awk只有一个文
件(/bin/awk),而且几乎每个版本的UNIX都提供各自版本的awk,你完全不必费心去想如何获得awk。但C语言却不是这样,虽然C语言是
UNIX天然的开发工具,但这个开发工具却是单独发行的,换言之,你必须为你的UNIX版本的C语言开发工具单独付费(当然使用D版者除外),获得并安装
它,然后你才可以使用它。 

基于以上理由,再加上awk强大的功能,我们有理由说,如果你要处理与文本样式扫描相关的工作,awk应该是
你的第一选择。在这里有一个可遵循的一般原则:如果你用普通的shell工具或shell script有困难的话,试试awk,如果awk仍不能解决问
题,则便用C语言,如果C语言仍然失败,则移至C++。 

awk的调用方式 

前面曾经说过,awk提供了适应多种需要的不同解决方案,它们是: 

一、
awk命令行,你可以象使用普通UNIX命令一样使用awk,在命令行中你也可以使用awk程序设计语言,虽然awk支持多行的录入,但是录入长长的命令
行并保证其正确无误却是一件令人头疼的事,因此,这种方法一般只用于解决简单的问题。当然,你也可以在shell script程序中引用awk命令行甚
至awk程序脚本。 

二、使用-f选项调用awk程序。awk允许将一段awk程序写入一个文本文件,然后在awk命令行中用-f选项调用并执行这段程序。具体的方法我们将在后面的awk语法中讲到。 

三、利用命令解释器调用awk程序:利用UNIX支持的命令解释器功能,我们可以将一段awk程序写入文本文件,然后在它的第一行加上: 
#!/bin/awk -f 
并赋予这个文本文件以执行的权限。这样做之后,你就可以在命令行中用类似于下面这样的方式调用并执行这段awk程序了。 

$awk脚本文本名 待处理文件 

awk的语法: 

与其它UNIX命令一样,awk拥有自己的语法: 

awk [ -F re] [parameter...] ['prog'] [-f progfile][in_file...] 

参数说明: 

-F re:允许awk更改其字段分隔符。 

parameter: 该参数帮助为不同的变量赋值。 

'prog': awk的程序语句段。这个语句段必须用单拓号:'和'括起,以防被shell解释。这个程序语句段的标准形式为: 

'pattern {action}' 


中pattern参数可以是egrep正则表达式中的任何一个,它可以使用语法/re/再加上一些样式匹配技巧构成。与sed类似,你也可以使用","分
开两样式以选择某个范围。关于匹配的细节,你可以参考附录,如果仍不懂的话,找本UNIX书学学grep和sed(本人是在学习ed时掌握匹配技术的)。
action参数总是被大括号包围,它由一系统awk语句组成,各语句之间用";"分隔。awk解释它们,并在pattern给定的样式匹配的记录上执行
其操作。与shell类似,你也可以使用“#”作为注释符,它使“#”到行尾的内容成为注释,在解释执行时,它们将被忽略。你可以省略pattern和
action之一,但不能两者同时省略,当省略pattern时没有样式匹配,表示对所有行(记录)均执行操作,省略action时执行缺省的操作——在
标准输出上显示。 

-f progfile:允许awk调用并执行progfile指定有程序文件。progfile是一个文本文件,他必须符合awk的语法。 

in_file:awk的输入文件,awk允许对多个输入文件进行处理。值得注意的是awk不修改输入文件。如果未指定输入文件,awk将接受标准输入,并将结果显示在标准输出上。awk支持输入输出重定向。 

awk的记录、字段与内置变量: 


面说过,awk处理的工作与数据库的处理方式有相同之处,其相同处之一就是awk支持对记录和字段的处理,其中对字段的处理是grep和sed不能实现
的,这也是awk优于二者的原因之一。在awk中,缺省的情况下总是将文本文件中的一行视为一个记录,而将一行中的某一部分作为记录中的一个字段。为了操
作这些不同的字段,awk借用shell的方法,用$1,$2,$3...这样的方式来顺序地表示行(记录)中的不同字段。特殊地,awk用$0表示整个
行(记录)。不同的字段之间是用称作分隔符的字符分隔开的。系统默认的分隔符是空格。awk允许在命令行中用-F re的形式来改变这个分隔符。事实
上,awk用一个内置的变量FS来记忆这个分隔符。awk中有好几个这样的内置变量,例如,记录分隔符变量RS、当前工作的记录数NR等等,本文后面的附
表列出了全部的内置变量。这些内置的变量可以在awk程序中引用或修改,例如,你可以利用NR变量在模式匹配中指定工作范围,也可以通过修改记录分隔符
RS让一个特殊字符而不是换行符作为记录的分隔符。 

例:显示文本文件myfile中第七行到第十五行中以字符%分隔的第一字段,第三字段和第七字段: 

awk -F % 'NR==7,NR==15 {printf $1 $3 $7}' 

awk的内置函数 

awk
之所以成为一种优秀的程序设计语言的原因之一是它吸收了某些优秀的程序设计语言(例如C)语言的许多优点。这些优点之一就是内置函数的使用,awk定义并
支持了一系列的内置函数,由于这些函数的使用,使得awk提供的功能更为完善和强大,例如,awk使用了一系列的字符串处理内置函数(这些函数看起来与C
语言的字符串处理函数相似,其使用方式与C语言中的函数也相差无几),正是由于这些内置函数的使用,使awk处理字符串的功能更加强大。本文后面的附录中
列有一般的awk所提供的内置函数,这些内置函数也许与你的awk版本有些出入,因此,在使用之前,最好参考一下你的系统中的联机帮助。 


为内置函数的一个例子,我们将在这里介绍awk的printf函数,这个函数使得awk与c语言的输出相一致。实际上,awk中有许多引用形式都是从C语
言借用过来的。如果你熟悉C语言,你也许会记得其中的printf函数,它提供的强大格式输出功能曾经带我们许多的方便。幸运的是,我们在awk中又和它
重逢了。awk中printf几乎与C语言中一模一样,如果你熟悉C语言的话,你完全可以照C语言的模式使用awk中的printf。因此在这里,我们只
给出一个例子,如果你不熟悉的话,请随便找一本C语言的入门书翻翻。 

例:显示文件myfile中的行号和第3字段: 

$awk '{printf"%03d%s/n",NR,$1}' myfile 

在命令行使用awk 


照顺序,我们应当讲解awk程序设计的内容了,但在讲解之前,我们将用一些例子来对前面的知识进行回顾,这些例子都是在命令行中使用的,由此我们可以知道
在命令行中使用awk是多么的方便。这样做的原因一方面是为下面的内容作铺垫,另一方面是介绍一些解决简单问题的方法,我们完全没有必要用复杂的方法来解
决简单的问题----既然awk提供了较为简单的方法的话。 

例:显示文本文件mydoc匹配(含有)字符串"sun"的所有行。 

$awk '/sun/{print}' mydoc 

由于显示整个记录(全行)是awk的缺省动作,因此可以省略action项。 

$awk '/sun/' mydoc 

例:下面是一个较为复杂的匹配的示例: 

$awk '/[Ss]un/,/[Mm]oon/ {print}' myfile 

它将显示第一个匹配Sun或sun的行与第一个匹配Moon或moon的行之间的行,并显示到标准输出上。 

例:下面的示例显示了内置变量和内置函数length()的使用: 

$awk 'length($0)>80 {print NR}' myfile 

该命令行将显示文本myfile中所有超过80个字符的行号,在这里,用$0表示整个记录(行),同时,内置变量NR不使用标志符'$'。 

例:
作为一个较为实际的例子,我们假设要对UNIX中的用户进行安全性检查,方法是考察/etc下的passwd文件,检查其中的passwd字段(第二字
段)是否为"*",如不为"*",则表示该用户没有设置密码,显示出这些用户名(第一字段)。我们可以用如下语句实现: 

#awk -F: '$2=="" {printf("%s no password!/n",$1' /etc/passwd 

在这个示例中,passwd文件的字段分隔符是“:”,因此,必须用-F:来更改默认的字段分隔符,这个示例中也涉及到了内置函数printf的使用。 

awk的变量 

如同其它程序设计语言一样,awk允许在程序语言中设置变量,事实上,提供变量的功能是程序设计语言的其本要求,不提供变量的程序设计语言本人还从未见过。 

awk
提供两种变量,一种是awk内置的变量,这前面我们已经讲过,需要着重指出的是,与后面提到的其它变量不同的是,在awk程序中引用内置变量不需要使用标
志符"$"(回忆一下前面讲过的NR的使用)。awk提供的另一种变量是自定义变量。awk允许用户在awk程序语句中定义并调用自已的变量。当然这种变
量不能与内置变量及其它awk保留字相同,在awk中引用自定义变量必须在它前面加上标志符"$"。与C语言不同的是,awk中不需要对变量进行初始
化,awk根据其在awk中第一次出现的形式和上下文确定其具体的数据类型。当变量类型不确定时,awk默认其为字符串类型。这里有一个技巧:如果你要让
你的awk程序知道你所使用的变量的明确类型,你应当在在程序中给它赋初值。在后面的实例中,我们将用到这一技巧。 

运算与判断: 


为一种程序设计语言所应具有的特点之一,awk支持多种运算,这些运算与C语言提供的几本相同:如+、-、*、/、%等等,同时,awk也支持C语言中类
似++、--、+=、-=、=+、=-之类的功能,这给熟悉C语言的使用者编写awk程序带来了极大的方便。作为对运算功能的一种扩展,awk还提供了一
系列内置的运算函数(如log、sqr、cos、sin等等)和一些用于对字符串进行操作(运算)的函数(如length、substr等等)。这些函数
的引用大大的提高了awk的运算功能。 

作为对条件转移指令的一部分,关系判断是每种程序设计语言都具备的功能,awk也不例外。awk
中允许进行多种测试,如常用的==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、>=(小于等于)等
等,同时,作为样式匹配,还提供了~(匹配于)和!~(不匹配于)判断。 

作为对测试的一种扩充,awk也支持用逻辑运算符:!(非)、&&(与)、||(或)和括号()进行多重判断,这大大增强了awk的功能。本文的附录中列出了awk所允许的运算、判断以及操作符的优先级。 

awk的流程控制 

流程控制语句是任何程序设计语言都不能缺少的部分。任何好的语言都有一些执行流程控制的语句。awk提供的完备的流程控制语句类似于C语言,这给我们编程带来了极大的方便。 

1、BEGIN和END: 


awk中两个特别的表达式,BEGIN和END,这两者都可用于pattern中(参考前面的awk语法),提供BEGIN和END的作用是给程序赋予初
始状态和在程序结束之后执行一些扫尾的工作。任何在BEGIN之后列出的操作(在{}内)将在awk开始扫描输入之前执行,而END之后列出的操作将在扫
描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。 

例:累计销售文件xs中的销售金额(假设销售金额在记录的第三字段): 

$awk 
>'BEGIN { FS=":";print "统计销售金额";total=0} 
>{print $3;total=total+$3;} 
>END {printf "销售金额总计:%.2f",total}' sx 
(注:>是shell提供的第二提示符,如要在shell程序awk语句和awk语言中换行,则需在行尾加反斜杠/) 

在这里,BEGIN预置了内部变量FS(字段分隔符)和自定义变量total,同时在扫描之前显示出输出行头。而END则在扫描完成后打印出总合计。 

2、流程控制语句 
awk提供了完备的流程控制语句,其用法与C语言类似。下面我们一一加以说明: 

2.1、if...else语句: 

格式: 
if(表达式) 
语句1 
else 
语句2 

格式中"语句1"可以是多个语句,如果你为了方便awk判断也方便你自已阅读,你最好将多个语句用{}括起来。awk分枝结构允许嵌套,其格式为: 

if(表达式1) 
{if(表达式2) 
语句1 
else 
语句2 

语句3 
else {if(表达式3) 
语句4 
else 
语句5 

语句6 

当然实际操作过程中你可能不会用到如此复杂的分枝结构,这里只是为了给出其样式罢了。 

2.2、while语句 

格式为: 

while(表达式) 
语句 

2.3、do-while语句 

格式为: 

do 

语句 
}while(条件判断语句) 

2.4、for语句 

格式为: 

for(初始表达式;终止条件;步长表达式) 
{语句} 


awk的 while、do-while和for语句中允许使用break,continue语句来控制流程走向,也允许使用exit这样的语句来退出。
break中断当前正在执行的循环并跳到循环外执行下一条语句。continue从当前位置跳到循环开始处执行。对于exit的执行有两种情况:当
exit语句不在END中时,任何操作中的exit命令表现得如同到了文件尾,所有模式或操作执行将停止,END模式中的操作被执行。而出现在END中的
exit将导致程序终止。 

例:为了 

awk中的自定义函数 

定义和调用用户自己的函数是几乎每个高级语言都具有的功能,awk也不例外,但原始的awk并不提供函数功能,只有在nawk或较新的awk版本中才可以增加函数。 

函数的使用包含两部分:函数的定义与函数调用。其中函数定义又包括要执行的代码(函数本身)和从主程序代码传递到该函数的临时调用。 

awk函数的定义方法如下: 

function 函数名(参数表){ 
函数体 

在gawk中允许将function省略为func,但其它版本的awk不允许。函数名必须是一个合法的标志符,参数表中可以不提供参数(但在调用函数时函数名后的一对括号仍然是不可缺少的),也可以提供一个或多个参数。与C语言相似,awk的参数也是通过值来传递的。 


awk中调用函数比较简单,其方法与C语言相似,但awk比C语言更为灵活,它不执行参数有效性检查。换句话说,在你调用函数时,可以列出比函数预计(函
数定义中规定)的多或少的参数,多余的参数会被awk所忽略,而不足的参数,awk将它们置为缺省值0或空字符串,具体置为何值,将取决于参数的使用方
式。 

awk函数有两种返回方式:隐式返回和显式返回。当awk执行到函数的结尾时,它自动地返回到调用程序,这是函数是隐式返回的。如果需要在结束之前退出函数,可以明确地使用返回语句提前退出。方法是在函数中使用形如:return 返回值 格式的语句。 

例:
下面的例子演示了函数的使用。在这个示例中,定义了一个名为print_header的函数,该函数调用了两个参数FileName和
PageNum,FileName参数传给函数当前使用的文件名,PageNum参数是当前页的页号。这个函数的功能是打印(显示)出当前文件的文件名,
和当前页的页号。完成这个功能后,这个函数将返回下一页的页号。 

nawk 
>'BEGIN{pageno=1;file=FILENAME 
>pageno=print_header(file,pageno);#调用函数print_header 
>printf("当前页页号是:%d/n",pageno); 
>} 

>#定义函数print_header 
>function print_header(FileName,PageNum){ 
>printf("%s %d/n",FileName,PageNum); >PageNum++;return PageNUm; 
>} 
>}' myfile 

执行这个程序将显示如下内容: 

myfile 1 
当前页页号是:2 

awk高级输入输出 

1.读取下一条记录: 

awk的next语句导致awk读取下一个记录并完成模式匹配,然后立即执行相应的操作。通常它用匹配的模式执行操作中的代码。next导致这个记录的任何额外匹配模式被忽略。 

2.简单地读取一条记录 

awk
的 getline语句用于简单地读取一条记录。如果用户有一个数据记录类似两个物理记录,那么getline将尤其有用。它完成一般字段的分离(设置字
段变量$0 FNR NF NR)。如果成功则返回1,失败则返回0(到达文件尾)。如果需简单地读取一个文件,则可以编写以下代码: 

例:示例getline的使用 

{while(getline==1) 

#process the inputted fields 

也可以使getline保存输入数据在一个字段中,而不是通过使用getline variable的形式处理一般字段。当使用这种方式时,NF被置成0,FNR和NR被增值。 


户也可以使用getline<"filename"方式从一个给定的文件中输入数据,而不是从命令行所列内容输入数据。此时,getline将完成
一般字段分离(设置字段变量$0和NF)。如果文件不存在,返回-1,成功,返回1,返回0表示失败。用户可以从给定文件中读取数据到一个变量中,也可以
用stdin(标准输入设备)或一个包含这个文件名的变量代替filename。值得注意的是当使用这种方式时不修改FNR和NR。 

另一种使用getline语句的方法是从UNIX命令接受输入,例如下面的例子: 

例:示例从UNIX命令接受输入 

{while("who -u"|getline) 

#process each line from the who command 

当然,也可以使用如下形式: 

"command" | getline variable 

3.关闭文件: 

awk中允许在程序中关闭一个输入或输出文件,方法是使用awk的close语句。 

close("filename") 

filename可以是getline打开的文件(也可以是stdin,包含文件名的变量或者getline使用的确切命令)。或一个输出文件(可以是stdout,包含文件名的变量或使用管道的确切命令)。 

4.输出到一个文件: 

awk中允许用如下方式将结果输出到一个文件: 

printf("hello word!/n")>"datafile" 
或 
printf("hello word!/n")>>"datafile" 

5.输出到一个命令 

awk中允许用如下方式将结果输出到一个命令: 

printf("hello word!/n")|"sort-t','" 

awk与shell script混合编程 


为awk可以作为一个shell命令使用,因此awk能与shell批处理程序很好的融合在一起,这给实现awk与shell程序的混合编程提供了可能。
实现混合编程的关键是awk与shell script之间的对话,换言之,就是awk与shell script之间的信息交流:awk从
shell script中获取所需的信息(通常是变量的值)、在awk中执行shell命令行、shell script将命令执行的结果送给awk处
理以及shell script读取awk的执行结果等等。 

1.awk读取Shell script程序变量 

在awk中我们可以通过“'$变量名'”的方式读取sell scrpit程序中的变量。 

例:在下面的示例中,我们将读取sell scrpit程序中的变量Name,该变量存放的是文本myfile的撰写者,awk将打印出这个人名。 

$cat writename 

# @(#) 




Name="张三" nawk 'BEGIN {name="'Name'";/ printf("/t%s/t撰写者%s/n",FILENAME,name");}/ 
{...}END{...}' myfile 


2.将shell命令的执行结果送给awk处理 

作为信息传送的一种方法,我们可以将一条shell命令的结果通过管道线(|)传递给awk处理: 

例:示例awk处理shell命令的执行结果 

$who -u | awk '{printf("%s正在执行%s/n",$2,$1)}' 

该命令将打印出注册终端正在执行的程序名。 

3.shell script程序读awk的执行结果 


了实现shell script程序读取awk执行的结果,我们可以采取一些特殊的方法,例如我们可以用变量名=`awk语句`的形式将awk执行的结果
存放入一个shell script变量。当然也可以用管道线的方法将awk执行结果传递给shell script程序处理。 

例:作
为传送消息的机制之一,UNIX提供了一个向其所有用户传送消息的命令wall(意思是write to all写给所有用户),该命令允许向所有工作中
的用户(终端)发送消息。为此,我们可以通过一段shell批处理程序wall.shell来模拟这一程序(事实上比较老的版本中wall就是一段
shell批处理程序: 

$cat wall.shell 

# @(#) wall.shell:发送消息给每个已注册终端 

cat >/tmp/$$ 
#用户录入消息文本 who -u | awk '{print $2}' | while read tty 
do 
cat /tmp/$$>$tty 
done 


这个程序里,awk接受who -u命令的执行结果,该命令打印出所有已注册终端的信息,其中第二个字段是已注册终端的设备名,因此用awk命令析出该设
备名,然后用while read tty语句循环读出这些文件名到变量(shell script变量)tty中,作为信息传送的终结地址。 

4.在awk中执行shell命令行----嵌入函数system() 

system()是一个不适合字符或数字类型的嵌入函数,该函数的功能是处理作为参数传递给它的字符串。system对这个参数的处理就是将其作为命令处理,也就是说将其当作命令行一样加以执行。这使得用户在自己的awk程序需要时可以灵活地执行命令或脚本。 

例:下面的程序将使用system嵌入函数打印用户编制好的报表文件,这个文件存放在名为myreport.txt的文件中。为简约起见,我们只列出了其END部分: 




END {close("myreport.txt");system("lp myreport.txt");} 

在这个示例中,我们首先使用close语句关闭了文件myreport.txt文件,然后使用system嵌入函数将myreport.txt送入打印机打印。 


到这里,我不得不跟朋友们说再见了,实在地说,这些内容仍然是awk的初步知识,电脑永远是前进的科学,awk也不例外,本篇所能做的只是在你前行的漫漫
长途中铺平一段小小开端,剩下的路还得靠你自己去走。老实说,如果本文真能给你前行的路上带来些许的方便,那本人就知足了! 

如对本篇有任何疑问,请E-mail To:Chizlong@yeah.net或到主页http://chizling.yeah.net中留言。 

附录: 

1.awk的常规表达式元字符 

/ 换码序列 
^ 在字符串的开头开始匹配 
$ 在字符串的结尾开始匹配 
. 与任何单个字符串匹配 
[ABC] 与[]内的任一字符匹配 
[A-Ca-c] 与A-C及a-c范围内的字符匹配(按字母表顺序) 
[^ABC] 与除[]内的所有字符以外的任一字符匹配 
Desk|Chair 与Desk和Chair中的任一个匹配 
[ABC][DEF] 关联。与A、B、C中的任一字符匹配,且其后要跟D、E、F中的任一个字符。 
* 与A、B或C中任一个出现0次或多次的字符相匹配 
+ 与A、B或C中任何一个出现1次或多次的字符相匹配 
? 与一个空串或A、B或C在任何一个字符相匹配 
(Blue|Black)berry 合并常规表达式,与Blueberry或Blackberry相匹配 

2.awk算术运算符 

运算符 用途 
------------------ 
x^y x的y次幂 
x**y 同上 
x%y 计算x/y的余数(求模) 
x+y x加y 
x-y x减y 
x*y x乘y 
x/y x除y 
-y 负y(y的开关符号);也称一目减 
++y y加1后使用y(前置加) 
y++ 使用y值后加1(后缀加) 
--y y减1后使用y(前置减) 
y-- 使用后y减1(后缀减) 
x=y 将y的值赋给x 
x+=y 将x+y的值赋给x 
x-=y 将x-y的值赋给x 
x*=y 将x*y的值赋给x 
x/=y 将x/y的值赋给x x%=y 将x%y的值赋给x 
x^=y 将x^y的值赋给x 
x**=y 将x**y的值赋给x 

3.awk允许的测试: 

操作符 含义 

x==y x等于y 
x!=y x不等于y 
x>y x大于y 
x>=y x大于或等于y 
x<y x小于y 
x<=y x小于或等于y? 
x~re x匹配正则表达式re? 
x!~re x不匹配正则表达式re? 

4.awk的操作符(按优先级升序排列) 

= 、+=、 -=、 *= 、/= 、 %= 
|| 
&& 
> >= < <= == != ~ !~ 
xy (字符串连结,'x''y'变成"xy") 
+ - 
* / % 
++ -- 

5.awk内置变量(预定义变量) 

说明:表中v项表示第一个支持变量的工具(下同):A=awk,N=nawk,P=POSIX awk,G=gawk 

V 变量 含义 缺省值 
-------------------------------------------------------- 
N ARGC 命令行参数个数 
G ARGIND 当前被处理文件的ARGV标志符 
N ARGV 命令行参数数组 
G CONVFMT 数字转换格式 %.6g 
P ENVIRON UNIX环境变量 
N ERRNO UNIX系统错误消息 
G FIELDWIDTHS 输入字段宽度的空白分隔字符串 
A FILENAME 当前输入文件的名字 
P FNR 当前记录数 
A FS 输入字段分隔符 空格 
G IGNORECASE 控制大小写敏感0(大小写敏感) 
A NF 当前记录中的字段个数 
A NR 已经读出的记录数 
A OFMT 数字的输出格式 %.6g 
A OFS 输出字段分隔符 空格 
A ORS 输出的记录分隔符 新行 
A RS 输入的记录他隔符 新行 
N RSTART 被匹配函数匹配的字符串首 
N RLENGTH 被匹配函数匹配的字符串长度 
N SUBSEP 下标分隔符 "/034" 

6.awk的内置函数 

V 函数 用途或返回值 
------------------------------------------------ 
N gsub(reg,string,target) 每次常规表达式reg匹配时替换target中的string 
N index(search,string) 返回string中search串的位置 
A length(string) 求串string中的字符个数 
N match(string,reg) 返回常规表达式reg匹配的string中的位置 
N printf(format,variable) 格式化输出,按format提供的格式输出变量variable。 
N split(string,store,delim) 根据分界符delim,分解string为store的数组元素 
N sprintf(format,variable) 返回一个包含基于format的格式化数据,variables是要放到串中的数据 
G strftime(format,timestamp) 返回一个基于format的日期或者时间串,timestmp是systime()函数返回的时间 
N sub(reg,string,target) 第一次当常规表达式reg匹配,替换target串中的字符串 
A substr(string,position,len) 返回一个以position开始len个字符的子串 
P totower(string) 返回string中对应的小写字符 
P toupper(string) 返回string中对应的大写字符 
A atan(x,y) x的余切(弧度) 
N cos(x) x的余弦(弧度) 
A exp(x) e的x幂 
A int(x) x的整数部分 
A log(x) x的自然对数值 
N rand() 0-1之间的随机数 
N sin(x) x的正弦(弧度) 
A sqrt(x) x的平方根 
A srand(x) 初始化随机数发生器。如果忽略x,则使用system() 
G system() 返回自1970年1月1日以来经过的时间(按秒计算)

Unix awk命令(2) -- awk命令手册

1.调用awk:
第一种方式:命令行方式
awk [-F field-separator] 'commands' input-file(s)
[-F域分隔符]是可选的,因为awk使用空格作为缺省的域分隔符,因此如果要浏览域间有空格的文本,不必指定这个选项,如果要浏览诸如passwd文件,此文件各域以冒号作为分隔符,则必须指明-F选项,如:
awk -F: 'commands' input-file
第二种方式是将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它。
第三种方式是将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-scrīpt-file input-files(s)
-f选项指明在文件awk_scrīpt_file中的awk脚本,input_file(s)是使用awk进行浏览的文件名。

2.awk脚本
2.1 模式和动作
任何awk语句都由模式和动作组成。在一个awk脚本中可能有许多语句。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。如果省略模式部分,动作将时刻保持执行状态。

式可以是任何条件语句或复合语句或正则表达式。模式包括两个特殊字段
BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文本开始执行。END语
句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志。
2.2 域和记录
使用$1,$3表示参照第1和第3域,注意这里用逗号做域分隔。如果希望打印一个有5个域的记录的所有域,可使用$0,意即所有域。
为打印一个域或所有域,使用print命令。这是一个awk动作
(1) 抽取域
(2) 保存awk输出
$ awk '{print $0}' grade.txt > wow
使用这种方法,显示屏上不会显示输出结果。直接输出到文件。
使用tee命令,在输出文件的同时,输出到屏幕
$ awk '{print $0}' grade.txt | tee delete_me_and_die
(3) 使和标准输入
使用awk脚本输入文件格式:
● $ belts.awk grade_student.txt
● $ belts.awk < grade2.txt
● $ grade2.txt | belts.awk
(4) 打印所有记录
$ awk '{print $0}' grade.txt
(5) 打印单独记录
$ awk '{print $1,$4}' grade.txt
(6) 打印报告头
域间使用/t进行划分。下划线使用/n强迫启动新行
$ awk 'BEGIN {print "Name Belt/n----------------------------------"} {print $1"/t"$4}' grade.txt
(7) 打印信息尾
使用END语句
$ awk 'BEGIN {print "Name/n---------"} {print $1} END {"end-of-report"}' grade.txt
2.5 条件操作符
(1) 匹配:
$ awk '{if ($4~/Brown/) print $0}' grade.txt
如果在文本中查询字符串"Brown",使用/Brown/
$ awk '$0 ~ /Brown/' grade.txt
(2) 精确匹配
$ awk '$3 == "48" {print $0}' grade.txt
$ awk '{if ($3=="48") print $0}' grade.txt
(3) 不匹配
$ awk '$0 !~ /Brown/' grade.txt
$ awk '{if($4 !~ /Brown/) print $0' grade.txt
精确不匹配
$ awk '$4 != "Brwon-2" {print $0}' grade.txt
(4) 小于
$ awk '{if ($6 < $7) print $0 "$1 Try better at the next comp"}' grade.txt
(5) 小于等于
$ awk '{if ($6 <= $7) print $1}' grade.txt
(6) 大于
$ awk '{if ($6 > $7) print $1}' grade.txt
(7) 设置大小写
$ awk '/[Gg]reen/' grade.txt
(8) 任意字符
抽取名字,其记录第一域的第四个字符是a,使用句点.。表达式/^...a/意为行首前三个字符任意,第四个是a,尖角符号代表行首。
$ awk '$1 ~/^...a/' grade.txt
(9) 或关系匹配
为抽取级别为yellow或brown的记录,使用竖线符|。意为匹配|两边模式之一。注意,使用竖线符时,语句必须用圆括号括起来。
$ awk '$0~/(Yellow|Brown)/' grade.txt
(10) 行首
$ awk '/^48/' input-file
(11) AND
&& 意味着两边匹配均为真
$ awk '{if ($1 == "P.Bunny" && $4 == "Yellow") print $0}' grade.txt
(12) OR
$ awk '{if ($4 == "Yellow" || $4 ~ /Brown/) print $0}' grade.txt
2.6 awk内置变量
  最常用的一些变量
--------------------------------------------------------
 ARGC   命令行参数个数
 ARGV   命令行参数排列
 ENVIRON  支持队列中系统环境变量的使用
 FILENAME  awk浏览的文件名
 FNR   浏览文件的记录数
 FS   设置输入域分隔符,等价于命令行-F选项
 NF   浏览记录的域个数
 NR   已读的记录数
 OFS   输出域分隔符
 ORS   输出记录分隔符
 RS   控制记录分隔符
--------------------------------------------------------
2.7 NF、NR和FILENAME
NR代表记录处数
$ awk 'END {print NR}' grade.txt
$ 5
打印所有学生的记录,并带有其记录号,并在END部分打印输入文件名
NF显示一条记录中有几个域
$ awk '{print NF,NR,$0}END{print FILENAME}' grade.txt
在从文件中抽取信息时,先检查文件中是否有记录。使用AND实现
$ awk '{if (NR > 0 && $4~/Brown/) print $0}' grade.txt
NF的强大功能是将变量$PWD的返回值传入awk并显示其目录。这里需要指定域分隔符
$ pwd
/usr/local/etc
$ echo $PWD | awk -F/ '{print $NF}'
另一个例子是显示文件名:
$ echo "/usr/local/etc/rc.sybase" | awk -F/ '{print $NF}'
rc.sybase
2.8 awk操作符
awk使用操作符,基本表达式可以划分为数字型、字符串型、变量型、域及数组元素,
-----------------------------------------------------
 = += *= /= %= ^= 赋值操作符
 ?    条件表达操作符
 || && !   并、与、非
 ~ !~    匹配操作符,包括匹配与不匹配
 < <= == != >>  关系操作符
 + - * / % ^   算术操作符
 ++ --    前缀和后缀
-----------------------------------------------------
(1)设置输入域到域变量名
一般的变量名设置方式为name = $n,这里name为调用的域变量名,n为实际域号。
例如,设置学生域名为name,级别域名为belt,操作为name = $1; belts = $4。注意分号,它分隔awk命令。
$ awk '{name = $1; belts = $4; if(belts ~/Yellow/) print name " is belt " belts}' grade.txt
$ P.Bunny is belt Yellow
(2) 域值比较操作
有两种方式测试一数值域是否小于另一数值域
1)在BEGIN中给变量名赋值。
2)在关系操作中使用实际数值。
查询所有比赛中得分在27点的学生
$ awk '{if ($6 < 27) print $0}' grade.txt
J.Lulu          06/99   48317   green   9       24      26
J.Troll         07/99   4842    Brown-3 12      26      26
使用BEGIN
$ awk 'BEGIN {BASELINE="27"} {if ($6 < BASELINE) print $0}' grade.txt
(3) 修改数值域取值
当在awk中修改任何域时,修改的只是缓存里的awk复本。awk会在变量NR和NF变量中反映出修改痕迹。
$1=$1+5,会将域1数值加5,但要确保赋值域其子集为数值型。
修改M.Tansley的目前级别分域,
awk '{if ($1 == "M.Tansley") $6=$6-1; print $1, $6, $7}' grade.txt
(4) 修改文本域
修改文本域即对其重新赋值。需要做的就是赋给一个新的字符串。
$ awk '{if ($1 == "J.Troll") ($1 = "J.L.Troll"); print $1}' grade.txt
(5) 只显示修改记录
在模式后面使用花括号将只打印修改部分。取得模式,再根据模式结果实施操作。
$ awk '{if ($1 == "J.Troll") {$1 = "J.L.Troll"; print $1}}' grade.txt
(6) 创建新的输出域
如创建一个基于其他域的加法新域{$4 = $2 + $3},假定记录包含3上域,则域4为新建域。
在文件grade.txt中创建新域8保存域目前级别分与域域最高级别分的减法值。表达式为'{$8 = $7 - $6}',语法首先测试域目前级别分小于域最高组别分。
$ awk 'BEGIN {print "Name/t Difference"} {if ($6 < $7) {$8 = $7 - $6; print$1, $8}}' grade.txt
可以创建新域,赋给更有意义的变量名
$ awk 'BEGIN {print "Name/t Difference"} {if ($6 < $7) {diff = $7 - $6; print$1, diff}}' grade.txt
(7) 增加列值
为增加列数或进行运行结果统计,使用符号 +=。增加的结果赋给符号左边变量值,增加到变量的域在符号右边。例如将$1加入变量total,表达式为total+=$1。
将所有学生的'目前级别分'加在一起,方法是tot+=$6,tot即为awk浏览的整个文件的域6结果总和。
$ awk '{(tot+=$6)}; END {print "Club student total points : " tot}' grade.txt
Club student total points : 155
(8) 文件长度相加
在目录中查看文件时,快速查看所有文件的长度及其总和,但要排除子目录。使用ls -l,然后管道输出到awk
$ ls -l | awk '/^[^d]/ {print $9"/t"$5} {tot+=$5} END {print "total KB : " tot}'
data.f    193
grade.txt       179
grepstring      7
local.cshrc     136
local.login     157
local.profile   174
results.txt     2129
wow       179
total KB : 4690
(9) 内置的字符串函数
   awk内置字符串函数
-----------------------------------------------------------
 gsub(r,s)   在整个$0中用s替代r
 gsub(r,s,t)  在整个t中用s替代r
 index(s,t)   返回s中字符串t的第一个位置
 length(s)   返回s长度
 match(s,r)   测试s是否包含匹配r的字符串
 split(s,a,fs)  在fs上将s分成序列a
 sprint(fmt,exp)  返回经fmt格式化后的exp
 sub(r,s)   用$0中最左边最长的子串代替s
 substr(s,p)  返回字符串s中从p开始的后缀部分
 substr(s,p,n)  返回字符串s中从p开始长度为n的后缀部分
-----------------------------------------------------------
■gsub:
■index:
$ awk 'BEGIN {print index("Bunny", "ny")}' grade.txt
4
■length:
$ awk '$1 == "J.Troll" {print length($1)" "$1}' grade.txt
7 J.Troll
$ awk 'BEGIN{print length("A FEW GOOD MEN")}'
14
■match:如果不存在,返回0
■split
返回字符串数组元素个数。
$ awk 'BEGIN {print split("123#456#678", myarray, "#")}'
3
■sub
使用sub发现并替换模式的第一次出现位置。字符串STR包含'poped popo pill',执行下列sub命令
sub(/op/, "op", STR)。结果 'pOPed pope pill'
$ awk '$1 == "L.Tansley" {print substr($1, 1, 5)}' grade.txt
L.Tan
■substr:
它按照起始位置及长度返回字符串的一部分。
$ awk '$1 == "L.Tansley" {print substr($1, 1, 5)}' grade.txt
L.Tan
substr的另一种形式是返回字符串后缀或指定位置后面的字符
$ awk '{print substr($1, 3)}' grade.txt
在BEGIN部分定义字符串,在END部分返回从第t个字符开始抽取的子串。
$ awk 'BEGIN {STR="A FEW GOOD MEN"} END {print substr(STR, 7)}' grade.txt
GOOD MEN
■从shell中向awk传入字符串:
通过管道把字符串传入awk
$ echo "Stand-by" | awk '{print length($0)}'
8
设置文件名为一变量,管道输出到awk,返回不带扩展名的文件名
$ STR="mydoc.txt"
$ echo $STR | awk '{print substr($STR,1,5)}'
mydoc
(10)字符串屏蔽序列
使用字符串或正则表达式时,有时需要在输出中加入一新行或查询一元字符。
   awk中使用的屏蔽序列
------------------------------------------------------------
 /b 退格键   /t  tab键
 /f 走纸换页  /ddd  八进制值
 /n 新行    /c  任意其他特殊字符,例如//为返斜线符号
 /r 回车键  
------------------------------------------------------------
打印May Day,中间夹tab键,后跟两个新行,再打印May Day,这次使用八进制数
$ awk 'BEGIN{print "May/tDay/n/nMay/t/104/141/171"}'
(11) awk输出函数printf
   awk printf修饰符
----------------------------------------------------------------
  -   左对齐
  Width   域的步长,用0表示0步长
  .prec   最大字符串长度,或小数点右边的位数
----------------------------------------------------------------
   awk printf格式
-------------------------------------------------------------
  %c   ASCII字符
  %d   整数
  %e   浮点数,科学记数法
  %f   浮点数,例如(123.44)
  %g   awk决定使用哪种浮点数转换e或者f
  %o   八进制数
  %s   字符串
  %x   十六进制数
--------------------------------------------------------------
■ 字符转换
观察ASCII码中65的等价值。管道输出65到awk。
$ echo "65" | awk '{printf "%c/n", $0}'
A
当然也可以按同样方式使用awk得到同样结果
$ awk 'BEGIN {printf "%c/n", 65}'
A
所有的字符转换都一样,下面的例子表示进行浮点数转换后'999'的输出结果。整数传入后被加了小数点。
$ awk 'BEGIN {printf "%f/n", 999}'
■ 格式化输出
打印所有的学生名字和序列号,要求名字左对齐,15个字符长度,后跟序列号。注意/n换行符放在最后一个指示符后面。输出将自动分成两列。
$ awk '{printf "%-15s %s/n", $1, $3}' grade.txt
M.Tansley       48311
J.Lulu          48317
P.Bunny         48
J.Troll         4842
L.Tansley       4712
加入文本注释帮助理解报文含义。可在正文前嵌入头信息。
$ awk 'BEGIN {print "Name /t/tS.Number"} {printf "%-15s %s/n", $1, $3}' grade.txt
Name            S.Number
M.Tansley       48311
J.Lulu          48317
P.Bunny         48
J.Troll         4842
L.Tansley       4712
■ 向一行awk命令传值
在查看awk脚本前,先来查看怎样在awk命令行中传递变量。
awk执行前将值传入awk变量,需要将变量放在命令行中,格式如下:
awk 命令变量 = 输入文件值
在命令行中设置变量AGE等于10,然后传入awk中,查询年龄在10岁以下的所有学生
$ awk '{if ($5 < AGE) print $0}' AGE=10 grade.txt
要快速查看文件系统空间容量,观察其是否达到一定水平。
$ df -k | awk '($4 ~/^[0-9]/) {if ($4 < TRIGGER) print $6"/t"$4}' TRIGGER=56000
使用who命令,who命令第一列包含注册用户名。
# who | awk '{print $1 " is logged on"}'
root is logged on
root is logged on
sun is logged on
awk传入环境变量。使用环境变量LOGNAME支持当前用户名。
# who | awk '{if ($1 == user) print $1 " you are connected to" $2}' user=$LOGNAME
root you are connected toconsole
root you are connected topts/4

 

 

 

Unix awk命令(3) -- awk命令详解

原文链接: https://www.cnblogs.com/dym998877/archive/2012/04/30/2476611.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    Unix awk命令(1~3) -- awk命令

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/49005

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午12:44
下一篇 2023年2月9日 上午12:45

相关推荐