shell-14: linux awk 命令应用

来源:互联网 发布:蚁群算法数学模型 编辑:程序博客网 时间:2024/06/05 16:50
linux awk 命令应用:

awk的语法:
awk [ -F re] [parameter...] ['prog'] [-f progfile][in_file...]
参数说明:
-F re:允许awk更改其字段分隔符。
parameter: 该参数帮助为不同的变量赋值。
'prog': awk的程序语句段。这个语句段必须用单拓号:'和'括起,以防被shell解释。这个程序语句段的标准
形式为:
'pattern {action}'
其中pattern参数可以是egrep正则表达式中的任何一个,它可以使用语法/re/再加上一些样式匹配技巧构成。 
action参数总是被大括号包围,它由一系统awk语句组成,各语句之间用";"分隔。

变量名 含义
ARGIND  命令行中文件序号
ARGC 命令行参数的个数
ARGV 命令行参数数组
FILENAME 当前输入文件名
FNR 当前文件中的记录号
FS 输入域分隔符,默认为一个空格
RS 输入记录分隔符
NF 当前记录里域个数(列)
NR 到目前为止记录数(行)
OFS 输出域分隔符
ORS 输出记录分隔符

下面以/etc/passwd为例:
注释:/etc/passwd文件是Linux/UNIX安全的关键文件之一.该文件用于用户登录时校验 用户的口令,当然应当仅对root可写.文件中每行的一般格式为:
LOGNAME:PASSWORD:UID:GID:USERINFO:HOME:SHELL 
每行的头两项是登录名和加密后的口令,后面的两个数是UID和GID,接着的 一项是系统管理员想写入的有关该用户的任何信息,最后两项是两个路径名: 一个是分配给用户的HOME目录,第二个是用户登录后将执行的shell(若为空格则 缺省为/bin/sh). 

在命令行使用awk :
例:将打印当前行的全部内容:
awk '{ print $0 }' /etc/passwd
awk '{ print "" }' /etc/passwd
例:显示/etc/passwd 中的行号和以“:”分隔的第1列:
awk -F":" '{printf"%03d%s/n",NR,$1}' /etc/passwd 
例:显示/etc/passwd 匹配(含有)字符串"root"的所有行。
awk '/root/{print}' /etc/passwd 
由于显示整个记录(全行)是awk的缺省动作,因此可以省略action项。
awk '/root/' /etc/passwd 
例:它将显示第一个匹配P或p的行与第一个匹配M或m的行之间的行,并显示到标准输出上:
awk '/[Pp]/,/[Mm]/ {print}' /etc/passwd 
例:下面的示例显示了内置变量和内置函数length的使用:
awk 'length>50 {print NR}' /etc/passwd
该命令行将显示/etc/passwd中所有超过50个字符的行号。 

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 的 while、do-while和for语句中允许使用break,continue语句来控制流程走向,也允许使用exit这样的语句来退出。break 中断当前正在执行的循环并跳到循环外执行下一条语句。continue从当前位置跳到循环开始处执行。对于exit的执行有两种情况:当exit语句不在 END中时,任何操作中的exit命令表现得如同到了文件尾,所有模式或操作执行将停止,END模式中的操作被执行。而出现在END中的exit将导致程序终止。
例:
awk '{ i=1;while(i<NF) {print NF,$i;i++}}' file 通过while语句实现循环。
awk '{ for(i=1;i<NF;i++) {print NF,$i}}' file 通过for语句实现循环。
type file|awk -F "/" '
{ for(i=1;i<NF;i++)
{ if(i==NF-1) { printf "%s",$i }
else { printf "%s/",$i } }}' 显示一个文件的全路径。
用for和if显示日期
awk 'BEGIN {
for(j=1;j<=12;j++)
{ flag=0;
printf "/n%d月份/n",j;
for(i=1;i<=31;i++)
{
if (j==2&&i>28) flag=1;
if ((j==4||j==6||j==9||j==11)&&i>30) flag=1;
if (flag==0) {printf "%02d%02d ",j,i}
}
}
}'
 
awk函数的定义方法如下:
function 函数名(参数表){
函数体

例:下面的例子演示了函数的使用。在这个示例中,定义了一个名为print_header的函数,该函数调用了两个参数FileName和 PageNum, FileName参数传给函数当前使用的文件名,PageNum参数是当前页的页号。这个函数的功能是打印(显示)出当前文件的文件名,和当前页的页号。完成这个功能后,这个函数将返回下一页的页号。
awk
>'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中调用系统变量必须用单引号,如果是双引号,则表示字符串
Flag=abcd
awk '{print '$Flag'}' 结果为abcd
awk '{print "$Flag"}' 结果为$Flag

表达式与代码块:
$2 == "fred" { print $3 }   //显示第二域为fred的第三个域
$1 ~ /root/ { print $3 }  //显示第一域匹配root的第三个域
例如:
[root@localhost ~]# awk -F":" '$1 ~ /root/ { print $0 }' /etc/passwd 
root:x:0:0:root:/root:/bin/bash