您的位置:首页 > 运维架构 > Shell

shell编程笔记-文本处理awk

2014-02-18 21:25 369 查看

第八章  文本处理利器 AWK

AWK是一种优良的文本处理工具。它不仅是Linux 中也是任何环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母)的最大功能取决于一个人所拥有的知识。AWK 提供了极其强大的功能:可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上 AWK 的确拥有自己的语言:AWK 程序设计语言,三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

最简单地说, AWK 是一种用于处理文本的编程语言工具。AWK 在很多方面类似于 shell 编程语言,尽管 AWK 具有完全属于其本身的语法。它的设计思想来源于 SNOBOL4 、sed 、Marc Rochkind设计的有效性语言、语言工具 yacc 和 lex ,当然还从 C 语言中获取了一些优秀的思想。在最初创造 AWK 时,其目的是用于文本处理,并且这种语言的基础是,只要在输入数据中有模式匹配,就执行一系列指令。该实用工具扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行。

尽管操作可能会很复杂,但命令的语法始终是:

awk '{pattern + action}' 或者 awk'pattern {action}'

其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号 ({}) 不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。

gawk 是 AWK 的 GNU 版本。

一般的UNIX作业系统,本身即附有AWK,不同的UNIX作业系统所附的AWK其版本亦不尽相同,若读者所使用的系统上未附有AWK,可通过anonymous ftp 到下列地方取得:

phi./pub/gnu

ftp/UNIX/gnu

preppub/gnu

注解:一种编程语言,因其模式匹配语法而特别有用,通常用于数据检索和数据转换。一个GNU版本称为Gawk。

 

小案例

 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ cat  /etc/fstab  
/dev/VolGroup00/LogVol00 /                       ext3    defaults        1 1  
LABEL=/boot             /boot                   ext3    defaults        1 2  
tmpfs                   /dev/shm                tmpfs   defaults        0 0  
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0  
sysfs                   /sys                    sysfs   defaults        0 0  
proc                    /proc                   proc    defaults        0 0  
/dev/VolGroup00/LogVol01 swap                    swap    defaults        0 0  
[houchangren@ebsdi-23260-oozie shell]$ awk  '{print $0}'  /etc/fstab  
/dev/VolGroup00/LogVol00 /                       ext3    defaults        1 1  
LABEL=/boot             /boot                   ext3    defaults        1 2  
tmpfs                   /dev/shm                tmpfs   defaults        0 0  
devpts                 /dev/pts                devpts  gid=5,mode=620  0 0  
sysfs                   /sys                    sysfs   defaults        0 0  
proc                    /proc                   proc    defaults        0 0  
/dev/VolGroup00/LogVol01 swap                    swap   defaults        0 0  
[houchangren@ebsdi-23260-oozie shell]$ awk  '{print}'  /etc/fstab  
/dev/VolGroup00/LogVol00 /                       ext3    defaults        1 1  
LABEL=/boot             /boot                   ext3    defaults        1 2  
tmpfs                   /dev/shm                tmpfs   defaults        0 0  
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0  
sysfs                   /sys                    sysfs   defaults        0 0  
proc                    /proc                   proc    defaults        0 0  
/dev/VolGroup00/LogVol01 swap                    swap    defaults        0 0  
[houchangren@ebsdi-23260-oozie shell]$ awk  '{print $1}'  /etc/fstab  
/dev/VolGroup00/LogVol00  
LABEL=/boot  
tmpfs  
devpts  
sysfs  
proc  
/dev/VolGroup00/LogVol01  
[houchangren@ebsdi-23260-oozie shell]$ awk  '{print "I am test"}'  /etc/fstab  
I am test  
I am test  
I am test  
I am test  
I am test  
I am test  
I am test  
[houchangren@ebsdi-23260-oozie shell]$  

[houchangren@ebsdi-23260-oozie shell]$ cat  /etc/fstab
/dev/VolGroup00/LogVol00 /                       ext3    defaults        1 1
LABEL=/boot             /boot                   ext3    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
/dev/VolGroup00/LogVol01 swap                    swap    defaults        0 0
[houchangren@ebsdi-23260-oozie shell]$ awk  '{print $0}'  /etc/fstab
/dev/VolGroup00/LogVol00 /                       ext3    defaults        1 1
LABEL=/boot             /boot                   ext3    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                 /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
/dev/VolGroup00/LogVol01 swap                    swap   defaults        0 0
[houchangren@ebsdi-23260-oozie shell]$ awk  '{print}'  /etc/fstab
/dev/VolGroup00/LogVol00 /                       ext3    defaults        1 1
LABEL=/boot             /boot                   ext3    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
/dev/VolGroup00/LogVol01 swap                    swap    defaults        0 0
[houchangren@ebsdi-23260-oozie shell]$ awk  '{print $1}'  /etc/fstab
/dev/VolGroup00/LogVol00
LABEL=/boot
tmpfs
devpts
sysfs
proc
/dev/VolGroup00/LogVol01
[houchangren@ebsdi-23260-oozie shell]$ awk  '{print "I am test"}'  /etc/fstab
I am test
I am test
I am test
I am test
I am test
I am test
I am test
[houchangren@ebsdi-23260-oozie shell]$


在文件  /etc/fstab中有六列

Device 装置名称

MountPoint 挂入点

Fstype 挂入类型

Options 参数

Dump 备份标示

Pass检查顺序,fsck用

关于fstab详细可参考:
http://hi.baidu.com/iezunhfiybhiour/item/e0348e8ca7c6562e100ef3ce

 

 

 

awk解释:

awk 是默认逐行读取,I am test 打印了,对应的行,

print $0就等于 print

print $1就取第一列。

 

 

基本语法

多个字段
awk常常被用于处理字段。所谓字段,就是在文本文件中,每一行分成许多列,列与列之间

用特定的符一号隔开。awk在这方面的处理能力特别强。

 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ awk'{print $1}' /etc/fstab  
/dev/VolGroup00/LogVol00  
LABEL=/boot  
tmpfs  
devpts  
sysfs  
proc  
/dev/VolGroup00/LogVol01  
[houchangren@ebsdi-23260-oozie shell]$ awk'{print $1 "\t " $3}' /etc/fstab  
/dev/VolGroup00/LogVol00         ext3  
LABEL=/boot      ext3  
tmpfs   tmpfs  
devpts  devpts  
sysfs   sysfs  
proc    proc  
/dev/VolGroup00/LogVol01         swap  
[houchangren@ebsdi-23260-oozie shell]$ awk'{print "device:" $1 "\tfstype: " $3}' /etc/fstab  
device:/dev/VolGroup00/LogVol00 fstype:ext3  
device:LABEL=/boot      fstype: ext3  
device:tmpfs    fstype: tmpfs  
device:devpts   fstype: devpts  
device:sysfs    fstype: sysfs  
device:proc     fstype: proc  
device:/dev/VolGroup00/LogVol01 fstype:swap  
[houchangren@ebsdi-23260-oozie shell]$  
   

[houchangren@ebsdi-23260-oozie shell]$ awk'{print $1}' /etc/fstab
/dev/VolGroup00/LogVol00
LABEL=/boot
tmpfs
devpts
sysfs
proc
/dev/VolGroup00/LogVol01
[houchangren@ebsdi-23260-oozie shell]$ awk'{print $1 "\t " $3}' /etc/fstab
/dev/VolGroup00/LogVol00         ext3
LABEL=/boot      ext3
tmpfs   tmpfs
devpts  devpts
sysfs   sysfs
proc    proc
/dev/VolGroup00/LogVol01         swap
[houchangren@ebsdi-23260-oozie shell]$ awk'{print "device:" $1 "\tfstype: " $3}' /etc/fstab
device:/dev/VolGroup00/LogVol00 fstype:ext3
device:LABEL=/boot      fstype: ext3
device:tmpfs    fstype: tmpfs
device:devpts   fstype: devpts
device:sysfs    fstype: sysfs
device:proc     fstype: proc
device:/dev/VolGroup00/LogVol01 fstype:swap
[houchangren@ebsdi-23260-oozie shell]$


指定列分隔符
 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie data]$ catpwd.piece  
root:x:0:0:root:/root:/bin/bash  
bin:x:1:1:bin:/bin:/sbin/nologin  
daemon:x:2:2:daemon:/sbin:/sbin/nologin  
adm:x:3:4:adm:/var/adm:/sbin/nologin  
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin  
sync:x:5:0:sync:/sbin:/bin/sync  
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown  
halt:x:7:0:halt:/sbin:/sbin/halt  
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin  
news:x:9:13:news:/etc/news:  
#指定冒号作为分隔符  
[houchangren@ebsdi-23260-oozie data]$ awk-F":" '{print "user:"$1 "\t shell:"$7}' pwd.piece  
user:root        shell:/bin/bash  
user:bin         shell:/sbin/nologin  
user:daemon      shell:/sbin/nologin  
user:adm         shell:/sbin/nologin  
user:lp shell:/sbin/nologin  
user:sync        shell:/bin/sync  
user:shutdown    shell:/sbin/shutdown  
user:halt        shell:/sbin/halt  
user:mail        shell:/sbin/nologin  
user:news       shell:  
   
#多个字符作为分隔符  
[houchangren@ebsdi-23260-oozie data]$ awk-F"[\t ]+" '{print "device:"$1 "\tfstype:"$3}'/etc/fstab  
device:/dev/VolGroup00/LogVol00 fstype:ext3  
device:LABEL=/boot      fstype:ext3  
device:tmpfs    fstype:tmpfs  
device:devpts   fstype:devpts  
device:sysfs    fstype:sysfs  
device:proc     fstype:proc  
device:/dev/VolGroup00/LogVol01 fstype:swap  
   
awk输入来源  
[houchangren@ebsdi-23260-oozie data]$ head-5 /etc/passwd | awk -F":" '{print "user:"$1 "\tshell:"$7}'  
user:root        shell:/bin/bash  
user:bin         shell:/sbin/nologin  
user:daemon      shell:/sbin/nologin  
user:adm         shell:/sbin/nologin  
user:lp shell:/sbin/nologin  
   

[houchangren@ebsdi-23260-oozie data]$ catpwd.piece
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
#指定冒号作为分隔符
[houchangren@ebsdi-23260-oozie data]$ awk-F":" '{print "user:"$1 "\t shell:"$7}' pwd.piece
user:root        shell:/bin/bash
user:bin         shell:/sbin/nologin
user:daemon      shell:/sbin/nologin
user:adm         shell:/sbin/nologin
user:lp shell:/sbin/nologin
user:sync        shell:/bin/sync
user:shutdown    shell:/sbin/shutdown
user:halt        shell:/sbin/halt
user:mail        shell:/sbin/nologin
user:news       shell:

#多个字符作为分隔符
[houchangren@ebsdi-23260-oozie data]$ awk-F"[\t ]+" '{print "device:"$1 "\tfstype:"$3}'/etc/fstab
device:/dev/VolGroup00/LogVol00 fstype:ext3
device:LABEL=/boot      fstype:ext3
device:tmpfs    fstype:tmpfs
device:devpts   fstype:devpts
device:sysfs    fstype:sysfs
device:proc     fstype:proc
device:/dev/VolGroup00/LogVol01 fstype:swap

awk输入来源
[houchangren@ebsdi-23260-oozie data]$ head-5 /etc/passwd | awk -F":" '{print "user:"$1 "\tshell:"$7}'
user:root        shell:/bin/bash
user:bin         shell:/sbin/nologin
user:daemon      shell:/sbin/nologin
user:adm         shell:/sbin/nologin
user:lp shell:/sbin/nologin


awk命令并不管文本来自何方,准确地说,awk读取标准输入。

当你将文本文件作为参数传递给awk命令时,awk命令打开文本文件,将之作为标准输入传递给awk的主逻辑。

 

awk语言特性

很多在UNIX、Linux中浸淫许久的人都称awk为一门语言。这不仅仅是对awk的恭维,其实awk作为一门语言当之无愧。除了在前面提及的最简单的文本处理功能,awk还具有计算机语言所特有的性质,例如变量、判断、循环,甚至数组。

 

awk代码结构
 

begin和end

 

在awk处理数据之前和之后可以添加代码块begin和end

 

 

在begin块中设置了,分隔符是冒号,和打印提示。

在end块中打印了结束提示。

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ catawk/fs.awk  
BEGIN{  
FS=":"  
print "I am begin!"  
}  
{  
print "USER:" $1  "\tshell:" $7  
}  
END{  
print "I am end!"  
}  
   
[houchangren@ebsdi-23260-oozie shell]$ head-5 /etc/passwd | awk -f awk/fs.awk  
I am begin!  
USER:root       shell:/bin/bash  
USER:bin        shell:/sbin/nologin  
USER:daemon     shell:/sbin/nologin  
USER:adm        shell:/sbin/nologin  
USER:lp shell:/sbin/nologin  
I am end!  
   
   
awk数据处理支持正则表达式如下  
   
[houchangren@ebsdi-23260-oozie shell]$ catawk/search.awk  
BEGIN{  
FS=":"  
}  
/nologin/ {++sum}  
END{  
print "'nologin' appears \t" sum  "\ttimes."  
   
}  
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/search.awk /etc/passwd  
'nologin' appears       32     times.  
   
   
//多项模式匹配  
[houchangren@ebsdi-23260-oozie shell]$ catawk/search.awk  
BEGIN{  
FS=":"  
}  
/nologin/ {++sum}  
/bash/{ ++bashs}  
END{  
print "we have \t" sum  "\t nologin users"  
print "we have \t " bashs"\t base  users"  
}  
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/search.awk /etc/passwd  
we have         32       nologin users  
we have          25      base users  
   

[houchangren@ebsdi-23260-oozie shell]$ catawk/fs.awk
BEGIN{
FS=":"
print "I am begin!"
}
{
print "USER:" $1  "\tshell:" $7
}
END{
print "I am end!"
}

[houchangren@ebsdi-23260-oozie shell]$ head-5 /etc/passwd | awk -f awk/fs.awk
I am begin!
USER:root       shell:/bin/bash
USER:bin        shell:/sbin/nologin
USER:daemon     shell:/sbin/nologin
USER:adm        shell:/sbin/nologin
USER:lp shell:/sbin/nologin
I am end!

awk数据处理支持正则表达式如下

[houchangren@ebsdi-23260-oozie shell]$ catawk/search.awk
BEGIN{
FS=":"
}
/nologin/ {++sum}
END{
print "'nologin' appears \t" sum  "\ttimes."

}
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/search.awk /etc/passwd
'nologin' appears       32     times.

//多项模式匹配
[houchangren@ebsdi-23260-oozie shell]$ catawk/search.awk
BEGIN{
FS=":"
}
/nologin/ {++sum}
/bash/{ ++bashs}
END{
print "we have \t" sum  "\t nologin users"
print "we have \t " bashs"\t base  users"
}
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/search.awk /etc/passwd
we have         32       nologin users
we have          25      base users


 

变量与数组
 

变量

在awk中有两种变量

1.      用户自定义变量

2.      内建变量

 

变量只存储字符串,当需要时再转换为其他类型

 

 awk的变量必须以ASCII字母或下划线开始,然后选择性地接上字毋、下划线及数字。如果

用正则表达式来匹配变量名的话,awk的变量名必须匹配[A-Za-z_][A-Za-z_0-9]*。

awk的变量名长度没有限制。

awk的变量名对大小写是敏感。

 

建议:

局部变量小写,全局变量第一个字母大写,内建变量全部大写。

 

Awk常用变量

 

属性
说明
$0
当前记录(作为单个变量)
$1~$n
当前记录的第n个字段,字段间由FS分隔
FS
输入字段分隔符 默认是空格
NF
当前记录中的字段个数,就是有多少列
NR
已经读出的记录数,就是行号,从1开始
RS
输入的记录分隔符默 认为换行符
OFS
输出字段分隔符 默认也是空格
ORS
输出的记录分隔符,默认为换行符
ARGC
命令行参数个数
ARGV
命令行参数数组
FILENAME
当前输入文件的名字
IGNORECASE
如果为真,则进行忽略大小写的匹配
ARGIND
当前被处理文件的ARGV标志符
CONVFMT
数字转换格式 %.6g
ENVIRON
UNIX环境变量
ERRNO
UNIX系统错误消息
FIELDWIDTHS
输入字段宽度的空白分隔字符串
FNR
当前记录数
OFMT
数字的输出格式 %.6g
RSTART
被匹配函数匹配的字符串首
RLENGTH
被匹配函数匹配的字符串长度
SUBSEP
\034
 

 

数组的使用无需声明即可使用。

 

数组

 

   awk中的数组命名遵循了与变量命名相同的惯例,数组包含了从零到多个数据项,通过紧接着名称的数组索引选定。

大部分程序语言都需要以整数表达式作为索引的数组,但是awk允许在数组名称之后,以方括号将任意数字或字符串表达式括起来作为索引。

 

数组的元素类型可以为多种类型。

数组的存储空间是稀疏的,比如存储1,和10000索引的数组值,它不会自动填充它们之间的值的。

 

 

 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozieshell]$ cat awk/array.awk  
BEGIN{  
arr[0]=0;  
arr[10000]=10000;  
arr["baidu"]="www.baidu.com";  
}  
   
//  
{  
print"init:\t" arr["baidu"];  
arr["baidu"]="www.baidu.cn";  
print"modifyed:\t" arr["baidu"];  
deletearr["baidu"];  
print"deleted:\t" arr["baidu"];  
   
}  
   
END{  
   
}  
[houchangren@ebsdi-23260-oozieshell]$ echo "test" |awk -f awk/array.awk  
test  
init:   www.baidu.com  
modifyed:       www.baidu.cn  
deleted:  
[houchangren@ebsdi-23260-oozieshell]$  
   
   

[houchangren@ebsdi-23260-oozieshell]$ cat awk/array.awk
BEGIN{
arr[0]=0;
arr[10000]=10000;
arr["baidu"]="www.baidu.com";
}

//
{
print"init:\t" arr["baidu"];
arr["baidu"]="www.baidu.cn";
print"modifyed:\t" arr["baidu"];
deletearr["baidu"];
print"deleted:\t" arr["baidu"];

}

END{

}
[houchangren@ebsdi-23260-oozieshell]$ echo "test" |awk -f awk/array.awk
test
init:   www.baidu.com
modifyed:       www.baidu.cn
deleted:
[houchangren@ebsdi-23260-oozieshell]$


环境变量操作

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$awk  'BEGIN{printENVIRON["HOME"];print ENVIRON["PATH"]}'  
/home/houchangren  
/usr/local/pig/pig-0.12.0/bin:/usr/java/jdk1.6.0_31/bin:/usr/maven3/bin/:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/java/jdk1.6.0_31:/usr/apache-ant-1.9.2/bin:/usr/local/hive-0.7.1-cdh3u6/bin:/home/hbase/hbase-0.94.10/bin:/root/bin  

[houchangren@ebsdi-23260-oozie shell]$awk  'BEGIN{printENVIRON["HOME"];print ENVIRON["PATH"]}'
/home/houchangren
/usr/local/pig/pig-0.12.0/bin:/usr/java/jdk1.6.0_31/bin:/usr/maven3/bin/:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/java/jdk1.6.0_31:/usr/apache-ant-1.9.2/bin:/usr/local/hive-0.7.1-cdh3u6/bin:/home/hbase/hbase-0.94.10/bin:/root/bin


 

 

算数运算和运算符
在awk中直接支持算术运算

 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print "3+5=" 3+5}'  
3+5=8  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print "2^10=" 2^10}'  
2^10=1024  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print "2*(5+10)=" 2*(5+10)}'  
2*(5+10)=30  

[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print "3+5=" 3+5}'
3+5=8
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print "2^10=" 2^10}'
2^10=1024
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print "2*(5+10)=" 2*(5+10)}'
2*(5+10)=30


 

 

小例子(判断是闰年还是平年)

 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ catawk/leap.awk  
BEGIN{  
print "Pick Your Leap Years";  
}  
/**app module*/  
{  
year =$1  
if((year%4==0&&year %100!=0) ||year%400==0)  
  print year " is leap year."  
else  
  print year "is not a leap year."  
   
}  
   
END{  
print "shell end"  
}  
[houchangren@ebsdi-23260-oozie shell]$  
   
[houchangren@ebsdi-23260-oozie shell]$ echo'2013' | awk -f awk/leap.awk;  
Pick Your Leap Years  
2013is not a leap year.  
shell end  
[houchangren@ebsdi-23260-oozie shell]$ echo'2000' | awk -f awk/leap.awk;  
Pick Your Leap Years  
2000 is leap year.  
shell end  
   

[houchangren@ebsdi-23260-oozie shell]$ catawk/leap.awk
BEGIN{
print "Pick Your Leap Years";
}
/**app module*/
{
year =$1
if((year%4==0&&year %100!=0) ||year%400==0)
print year " is leap year."
else
print year "is not a leap year."

}

END{
print "shell end"
}
[houchangren@ebsdi-23260-oozie shell]$

[houchangren@ebsdi-23260-oozie shell]$ echo'2013' | awk -f awk/leap.awk;
Pick Your Leap Years
2013is not a leap year.
shell end
[houchangren@ebsdi-23260-oozie shell]$ echo'2000' | awk -f awk/leap.awk;
Pick Your Leap Years
2000 is leap year.
shell end


awk中的运算符

 

运算符
描述
用法
 = += -= *= /= %= ^= **=
赋值语句
awk 'BEGIN{a=10;print a}'

awk 'BEGIN{a+=10;print a}'

awk 'BEGIN{a-=10;print a}'

awk 'BEGIN{a*=10;print a}'

awk 'BEGIN{a/=10;print a}'

awk 'BEGIN{a%=10;print a}'

awk 'BEGIN{a^=10;print a}'

awk 'BEGIN{a**=10;print a}'
?:
三元运算符
awk 'BEGIN{print (1==1)?"true":"false"}'
||
逻辑或
awk 'BEGIN{a=1;b=2;print (a>5 && b<=2),(a>5 || b<=2);}'
&&
逻辑与
awk 'BEGIN{a=1;b=2;print (a>5 && b<=2),(a>5 || b<=2);}'
~ ~!
匹配正则表达式和

不匹配正则表达式
awk 'BEGIN{a="IamTest";if(a ~ /^Iam*/){print a;}else{print "....."}}'

awk 'BEGIN{a="IamTest";if(a ~! /^Iam*/){print a;}else{print "....."}}'
< <= > >= != ==
关系运算符
略.
 + - * / %
加减乘除和取余
略.
^ **
幂函数
awk 'BEGIN{print 10**10}'

awk 'BEGIN{print 10^10}'
 ++ --
加加和减减,

是自身修改,

分前缀和后缀
 
$
字段引用
 echo "123123" |awk '{print $1}'
in
数组成员 判断 key是不是有
awk 'BEGIN{arr[0]="b";print(0 in arr)}'
 

 

判断和循环
Awk中的条件语句主要有if、else循环语句主要是for 和while

 

If实例

[html]
view plaincopyprint?





   
[root@ebsdi-23260-oozie ~]# awk'BEGIN{a=1;b=2;if(a>b){print"大于";}else{print"小于";}}'  
小于  
   
[root@ebsdi-23260-oozie ~]# awk'BEGIN{a=1;b=2;if(a>b){print"大于";}elseif(a==1){print "a=1";}else{ print"小于";}}'  
a=1  
   
   
while循环  
[root@ebsdi-23260-oozie ~]# awk'BEGIN{i=3;while(i>0){print i;i--}}'  
3  
2  
1  
Do while 循环  
[root@ebsdi-23260-oozie ~]# awk'BEGIN{i=3;do{print i;i--}while(i>0)}'  
3  
2  
1  
   
For循环  
[root@ebsdi-23260-oozie ~]# awk'BEGIN{for(i=3;i>0;i--){print i;}}'  
3  
2  
1  
   
Break中断循环  
[root@ebsdi-23260-oozie ~]# awk'BEGIN{i=3;while(i>0){if(i==2)break;print i;i--}}'  
3  
   
Continue跳过本次循环  
[root@ebsdi-23260-oozie ~]# awk'BEGIN{for(i=3;i>0;i--){if(i==2)continue;print i;}}'  
3  
1  

[root@ebsdi-23260-oozie ~]# awk'BEGIN{a=1;b=2;if(a>b){print"大于";}else{print"小于";}}'
小于

[root@ebsdi-23260-oozie ~]# awk'BEGIN{a=1;b=2;if(a>b){print"大于";}elseif(a==1){print "a=1";}else{ print"小于";}}'
a=1

while循环
[root@ebsdi-23260-oozie ~]# awk'BEGIN{i=3;while(i>0){print i;i--}}'
3
2
1
Do while 循环
[root@ebsdi-23260-oozie ~]# awk'BEGIN{i=3;do{print i;i--}while(i>0)}'
3
2
1

For循环
[root@ebsdi-23260-oozie ~]# awk'BEGIN{for(i=3;i>0;i--){print i;}}'
3
2
1

Break中断循环
[root@ebsdi-23260-oozie ~]# awk'BEGIN{i=3;while(i>0){if(i==2)break;print i;i--}}'
3

Continue跳过本次循环
[root@ebsdi-23260-oozie ~]# awk'BEGIN{for(i=3;i>0;i--){if(i==2)continue;print i;}}'
3
1


多行一条记录FS 和RS
 

在awk中除了有字段还有记录行的概念,默认情况下是一条行是一条记录,但是有时候一条记录可能跨多行。

如下

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ catdata/boys.txt  
Xiaoming  
10  
Beijing.china  
   
Xiaohou  
14  
Shanghai.china  
   
Lisha  
13  
Paris. France  
   

[houchangren@ebsdi-23260-oozie shell]$ catdata/boys.txt
Xiaoming
10
Beijing.china

Xiaohou
14
Shanghai.china

Lisha
13
Paris. France


 

在上文的awk变量中已经有表格说明了指定行RS和FS是记录分隔符和字段分隔符

 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozieshell]$ vim awk/boys.awk  
BEGIN{  
RS="";  
FS="\n"  
}  
{  
print$1 "\t" $2 "\t" $2  
}  
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/boys.awk  data/boys.txt  
Xiaoming        10     10  
Xiaohou 14      14  
Lisha  13      13  
   

[houchangren@ebsdi-23260-oozieshell]$ vim awk/boys.awk
BEGIN{
RS="";
FS="\n"
}
{
print$1 "\t" $2 "\t" $2
}
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/boys.awk  data/boys.txt
Xiaoming        10     10
Xiaohou 14      14
Lisha  13      13


 

 

 

 

 

设定ORS和OFS

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ vimawk/boys.awk  
   
BEGIN{  
RS="";  
FS="\n";  
ORS="\n\n";  
OFS=",";  
   
}  
{  
print $1","$2","$3  
}  
   
[houchangren@ebsdi-23260-oozie shell]$ awk-f  awk/boys.awk  data/boys.txt  
Xiaoming,10,Beijing.china  
   
Xiaohou,14,Shanghai.china  
   
Lisha,13,Paris. France  
   
[houchangren@ebsdi-23260-oozie shell]$  
   
[houchangren@ebsdi-23260-oozie shell]$ catawk/boys.awk  
BEGIN{  
RS="";  
FS="\n";  
ORS="";  
   
}  
{  
x=1  
while(x<=NF){  
print $x "\t"  
x++  
}  
print "\n"  
}  
   
[houchangren@ebsdi-23260-oozie shell]$ awk-f  awk/boys.awk  data/boys.txt  
Xiaoming        10     Beijing.china  
Xiaohou 14      Shanghai.china  
Lisha  13      Paris. France  

[houchangren@ebsdi-23260-oozie shell]$ vimawk/boys.awk

BEGIN{
RS="";
FS="\n";
ORS="\n\n";
OFS=",";

}
{
print $1","$2","$3
}

[houchangren@ebsdi-23260-oozie shell]$ awk-f  awk/boys.awk  data/boys.txt
Xiaoming,10,Beijing.china

Xiaohou,14,Shanghai.china

Lisha,13,Paris. France

[houchangren@ebsdi-23260-oozie shell]$

[houchangren@ebsdi-23260-oozie shell]$ catawk/boys.awk
BEGIN{
RS="";
FS="\n";
ORS="";

}
{
x=1
while(x<=NF){
print $x "\t"
x++
}
print "\n"
}

[houchangren@ebsdi-23260-oozie shell]$ awk-f  awk/boys.awk  data/boys.txt
Xiaoming        10     Beijing.china
Xiaohou 14      Shanghai.china
Lisha  13      Paris. France


 

用户自定义函数

 

格式
 

awk的用户自定义函数获取参数,选择性地返回标量值。函数可以定义在程序顶层的任意位置,定义的格式为:

 

[html]
view plaincopyprint?





function  functionName (args1,args2,….){  
//code block  
   
}  

function  functionName (args1,args2,….){
//code block

}


 

实例增加函数

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ catawk/fun_add.awk  
function add(x,y,sum){  
sum=x+y;  
return sum;  
}  
BEGIN{  
print "test function add";  
m=2;  
n=3;  
x=add(m,n);  
printf ("m:%d\n",m);  
printf ("n:%d\n",n);  
   
printf ("sum of m and n is%d",x);  
   
print("\n");  
   
}  
   
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/fun_add.awk  
test function add  
m:2  
n:3  
sum of m and n is 5  
   

[houchangren@ebsdi-23260-oozie shell]$ catawk/fun_add.awk
function add(x,y,sum){
sum=x+y;
return sum;
}
BEGIN{
print "test function add";
m=2;
n=3;
x=add(m,n);
printf ("m:%d\n",m);
printf ("n:%d\n",n);

printf ("sum of m and n is%d",x);

print("\n");

}

[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/fun_add.awk
test function add
m:2
n:3
sum of m and n is 5


参数引用
在awk中也有引用传递和值传递的一说

值引用(执行完swap函数后,值没变);

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ vimawk/fun_swap.awk  
   
function swap(x,y,temp){  
temp=x;  
x=y;  
y=temp;  
}  
BEGIN {}  
{  
m=3;  
n=2;  
   
printf("m:%d-----------n:%d\n",m,n);  
swap(m,n);  
printf("m:%d-----------n:%d\n",m,n);  
   
}  
[houchangren@ebsdi-23260-oozie shell]$ echo"" |awk -f awk/fun_swap.awk  
m:3-----------n:2  
m:3-----------n:2  
   

[houchangren@ebsdi-23260-oozie shell]$ vimawk/fun_swap.awk

function swap(x,y,temp){
temp=x;
x=y;
y=temp;
}
BEGIN {}
{
m=3;
n=2;

printf("m:%d-----------n:%d\n",m,n);
swap(m,n);
printf("m:%d-----------n:%d\n",m,n);

}
[houchangren@ebsdi-23260-oozie shell]$ echo"" |awk -f awk/fun_swap.awk
m:3-----------n:2
m:3-----------n:2


传递引用(执行完swap函数后,值变了);

 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ echo"" |awk -f awk/fun_swap2.awk  
arr[0]:10-----arr[1]11  
arr[0]:11-----arr[1]10  
[houchangren@ebsdi-23260-oozie shell]$ vimawk/fun_swap2.awk  
   
function swap(arr,temp){  
   
temp=arr[0];  
arr[0]=arr[1];  
arr[1]=temp;  
}  
BEGIN{}  
   
{  
arr[0]=10;  
arr[1]=11;  
   
printf("arr[0]:%d-----arr[1]%d\n",arr[0],arr[1]);  
swap(arr);  
printf("arr[0]:%d-----arr[1]%d\n",arr[0],arr[1]);  
   
   
   
}  
   
[houchangren@ebsdi-23260-oozie shell]$ echo"" |awk -f awk/fun_swap2.awk  
arr[0]:10-----arr[1]11  
arr[0]:11-----arr[1]10  
   

[houchangren@ebsdi-23260-oozie shell]$ echo"" |awk -f awk/fun_swap2.awk
arr[0]:10-----arr[1]11
arr[0]:11-----arr[1]10
[houchangren@ebsdi-23260-oozie shell]$ vimawk/fun_swap2.awk

function swap(arr,temp){

temp=arr[0];
arr[0]=arr[1];
arr[1]=temp;
}
BEGIN{}

{
arr[0]=10;
arr[1]=11;

printf("arr[0]:%d-----arr[1]%d\n",arr[0],arr[1]);
swap(arr);
printf("arr[0]:%d-----arr[1]%d\n",arr[0],arr[1]);

}

[houchangren@ebsdi-23260-oozie shell]$ echo"" |awk -f awk/fun_swap2.awk
arr[0]:10-----arr[1]11
arr[0]:11-----arr[1]10


递归调用
 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ echo-e "1\n3\n5\n10\n20\n35\n40" |awk -f awk/fun_fibonacci.awk  
------------  
1th of fibonacci sequence is 1  
------------  
3th of fibonacci sequence is 2  
------------  
5th of fibonacci sequence is 5  
------------  
10th of fibonacci sequence is 55  
------------  
20th of fibonacci sequence is 6765  
------------  
35th of fibonacci sequence is 9227465  
------------  
40th of fibonacci sequence is 102334155  
   

[houchangren@ebsdi-23260-oozie shell]$ echo-e "1\n3\n5\n10\n20\n35\n40" |awk -f awk/fun_fibonacci.awk
------------
1th of fibonacci sequence is 1
------------
3th of fibonacci sequence is 2
------------
5th of fibonacci sequence is 5
------------
10th of fibonacci sequence is 55
------------
20th of fibonacci sequence is 6765
------------
35th of fibonacci sequence is 9227465
------------
40th of fibonacci sequence is 102334155


 

由于上方的斐波那契的算法,特别忙,当执行35时候就得20秒左右40的时候好像就得10分钟左右了。

 

优化程序改为下方

 

[html]
view plaincopyprint?





   
[houchangren@ebsdi-23260-oozie shell]$ vimawk/fun_fibonacci2.awk  
   
ind =3'  
ind++;  
BEGIN{  
function fibonacci(array,n,ind){  
ind =3;  
while(ind<=n){  
array[ind]=array[ind-1]+array[ind-2];  
ind++;  
}  
   
}  
BEGIN{}  
/**code block*/  
{  
array[1]=1;  
array[2]=1;  
n=$1;  
fibonacci(array,n);  
printf("%dth of  fibonacci sequence is :%d\n",n,array
);  
   
}  
   
   
   
[houchangren@ebsdi-23260-oozie shell]$ echo-e "1\n3\n5\n10\n20\n30\n35\n50" |awk -f awk/fun_fibonacci2.awk  
1th of fibonacci sequence is : 1  
3th of fibonacci sequence is : 2  
5th of fibonacci sequence is : 5  
10th of fibonacci sequence is : 55  
20th of fibonacci sequence is : 6765  
30th of fibonacci sequence is : 832040  
35th of fibonacci sequence is : 9227465  
50th of fibonacci sequence is : 12586269025  

[houchangren@ebsdi-23260-oozie shell]$ vimawk/fun_fibonacci2.awk

ind =3'
ind++;
BEGIN{
function fibonacci(array,n,ind){
ind =3;
while(ind<=n){
array[ind]=array[ind-1]+array[ind-2];
ind++;
}

}
BEGIN{}
/**code block*/
{
array[1]=1;
array[2]=1;
n=$1;
fibonacci(array,n);
printf("%dth of  fibonacci sequence is :%d\n",n,array
);

}

[houchangren@ebsdi-23260-oozie shell]$ echo-e "1\n3\n5\n10\n20\n30\n35\n50" |awk -f awk/fun_fibonacci2.awk
1th of fibonacci sequence is : 1
3th of fibonacci sequence is : 2
5th of fibonacci sequence is : 5
10th of fibonacci sequence is : 55
20th of fibonacci sequence is : 6765
30th of fibonacci sequence is : 832040
35th of fibonacci sequence is : 9227465
50th of fibonacci sequence is : 12586269025


 

 

 

字符串和算术处理

格式化输出
 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ vimawk/print.awk  
   
BEGIN{}  
   
{  
x=1;  
b="foo";  
printf("my name is %s,I'm%s\n","xiaohouzi",10);  
myout=sprintf("%s=%s",b,x);  
print myout;  
}  
   
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk -f awk/print.awk  
my name is xiaohouzi,I'm 10  
foo=1  

[houchangren@ebsdi-23260-oozie shell]$ vimawk/print.awk

BEGIN{}

{
x=1;
b="foo";
printf("my name is %s,I'm%s\n","xiaohouzi",10);
myout=sprintf("%s=%s",b,x);
print myout;
}

[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk -f awk/print.awk
my name is xiaohouzi,I'm 10
foo=1


 

在printf和sprintf中操作时一样的,不同的时候sprintf可以将输出写到变量中,为变量赋值而使用。

 

 

转义符
转移字符
解释
%c
 单个字符
%s
字符串
%d
十进制有符号整数
%ld
十进制长整型
%u
十进制无符号整数
%lu
十进制无符号长整型数
%x
十六进制表示的整数
%lx
十六进制表示的长整数
%o
八进制整数
%lo
八进制长整数
%e
 指数形式的浮点数
%f
浮点数
%g
选e或者f中较短的一种形式
\n
 换行
\f
 清屏并换页
\r
 回车
\t
Tab符
\xhh
表示一个ASCII码用16进表示,

其中hh是1到2个16进制数
 

 

 

 

修饰符
 

 
字符
定义
 -
左对齐修饰符
 #
显示八进制的时候前边加个0,显示十六进制的时候前面加个0x
 +
显示使用d,e,f和g转换的整数时,加上正负号+或者-
0
用0而不是空白符来填充所显示的值
 
 

实例
 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10s|\n","ollir");}';  
|    ollir|  
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10s|\n","hello,ollir");}';  
|hello,ollir|  
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%-10s|\n","hello");}';  
|hello     |  
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10.5g|\n","hello");}';  
|        0|  
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10.5g|\n","023");}';  
|       23|  
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10.5g|\n",23.4454);}';  
|   23.445|  
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10.5g|\n",23.445433);}';  
|   23.445|  
[houchangren@ebsdi-23260-oozie shell]$ echo"10, 6, 19.123232342346345" | awk '{printf("|%*.*g|\n",$1,$2,$3);}';  
|  19.1232|  

[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10s|\n","ollir");}';
|    ollir|
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10s|\n","hello,ollir");}';
|hello,ollir|
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%-10s|\n","hello");}';
|hello     |
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10.5g|\n","hello");}';
|        0|
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10.5g|\n","023");}';
|       23|
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10.5g|\n",23.4454);}';
|   23.445|
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk '{printf("|%10.5g|\n",23.445433);}';
|   23.445|
[houchangren@ebsdi-23260-oozie shell]$ echo"10, 6, 19.123232342346345" | awk '{printf("|%*.*g|\n",$1,$2,$3);}';
|  19.1232|


 

字符串函数
 

 

函数
说明
gsub( Ere, Repl, [ In ] )
除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行,。
sub( Ere, Repl, [ In ] )
用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere 参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。
index( String1, String2 )
在由 String1 参数指定的字符串(其中有出现 String2 指定的参数)中,返回位置,从 1 开始编号。如果 String2 参数不在 String1 参数中出现,则返回 0(零)。
length [(String)]
返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。
blength [(String)]
返回 String 参数指定的字符串的长度(以字节为单位)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。
substr( String, M, [ N ] )
返回具有 N 参数指定的字符数量子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。M 参数指定为将 String 参数中的第一个字符作为编号 1。如果未指定 N 参数,则子串的长度将是 M 参数指定的位置到 String 参数的末尾 的长度。
match( String, Ere )
在 String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH 特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。
split( String, A, [Ere] )
将 String 参数指定的参数分割为数组元素 A[1], A[2], . . ., A
,并返回 n 变量的值。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere 参数)。除非上下文指明特定的元素还应具有一个数字值,否则 A 数组中的元素用字符串值来创建。
tolower( String )
返回 String 参数指定的字符串,字符串中每个大写字符将更改为小写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。
toupper( String )
返回 String 参数指定的字符串,字符串中每个小写字符将更改为大写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。
sprintf(Format, Expr, Expr, . . . )
根据 Format 参数指定的 printf 子例程格式字符串来格式化 Expr 参数指定的表达式并返回最后生成的字符串。
实例: 

字符串查找



[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{pos=index("hello,ollir","ollir");print pos;}'  
7  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{pos=index("hello ,ollir","ollir");print pos;}'  
9  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{pos=index("hello,ollir","ollirs");print pos;}'  
0  
   
   

[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{pos=index("hello,ollir","ollir");print pos;}'
7
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{pos=index("hello ,ollir","ollir");print pos;}'
9
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{pos=index("hello,ollir","ollirs");print pos;}'
0


 

自定义一个反向查询索引函数

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ vimawk/rindex.awk  
   
function rindex(string,find,k,ns,nf){  
   
ns=length(string);  
nf=length(find);  
   
for(k=ns+1-nf;k>nf;k--){  
 if(substr(string,k,nf)==find){  
       return k;  
    }  
}  
return 0;  
}  
BEGIN{}  
   
{  
string=$1;  
find=$2;  
   
printf("Reverse index of  %s in %s is :%d\n",find,string,rindex(string,find));  
   
}  
[houchangren@ebsdi-23260-oozie shell]$ echo"123456789012345 123" | awk -f awk/rindex.awk  
Reverse index of  123 in 123456789012345 is :11  

[houchangren@ebsdi-23260-oozie shell]$ vimawk/rindex.awk

function rindex(string,find,k,ns,nf){

ns=length(string);
nf=length(find);

for(k=ns+1-nf;k>nf;k--){
if(substr(string,k,nf)==find){
return k;
}
}
return 0;
}
BEGIN{}

{
string=$1;
find=$2;

printf("Reverse index of  %s in %s is :%d\n",find,string,rindex(string,find));

}
[houchangren@ebsdi-23260-oozie shell]$ echo"123456789012345 123" | awk -f awk/rindex.awk
Reverse index of  123 in 123456789012345 is :11


 

 

 

子字符串提取


 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ catdata/info.txt  
1.first is lilei  
2.second is liuhai  
3.thrid is zhangsan  
[houchangren@ebsdi-23260-oozie shell]$ awk'{print substr($1,3);}' data/info.txt  
first  
second  
third  
[houchangren@ebsdi-23260-oozie shell]$ awk'{print substr($3,0);}' data/info.txt  
lilei  
liuhai  
zhangsan  
[houchangren@ebsdi-23260-oozie shell]$ awk'{print substr($3,0,5);}' data/info.txt  
lilei  
liuha  
zhang  

[houchangren@ebsdi-23260-oozie shell]$ catdata/info.txt
1.first is lilei
2.second is liuhai
3.thrid is zhangsan
[houchangren@ebsdi-23260-oozie shell]$ awk'{print substr($1,3);}' data/info.txt
first
second
third
[houchangren@ebsdi-23260-oozie shell]$ awk'{print substr($3,0);}' data/info.txt
lilei
liuhai
zhangsan
[houchangren@ebsdi-23260-oozie shell]$ awk'{print substr($3,0,5);}' data/info.txt
lilei
liuha
zhang


 

字符串匹配
 

 

 

match函数提供了与正则匹配的操作。

 

awk除了返回子串的索引外,还有副作用:设置系统变量RSTART和RLENGTH。RSTART在match()函数运行后被设置为匹配上正则表达式的字符串的起始位置 , RLENGTH则被设置为匹配上正则表达式的子字符串的长度。如果无法完成匹配,则RSTART被设置为0,而RLENGTH被设置为-1。

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ echo"" |awk '{start=match("this is a test",/[a-z]+$/);printstart;}'  
11  
[houchangren@ebsdi-23260-oozie shell]$ echo"" |awk '{start=match("this is a test",/[a-z]+$/);printstart "," RSTART "," RLENGTH;}'  
11,11,4  
   

[houchangren@ebsdi-23260-oozie shell]$ echo"" |awk '{start=match("this is a test",/[a-z]+$/);printstart;}'
11
[houchangren@ebsdi-23260-oozie shell]$ echo"" |awk '{start=match("this is a test",/[a-z]+$/);printstart "," RSTART "," RLENGTH;}'
11,11,4


 

 

子字符串替换



[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ echo"test is test" | awk '{gsub(/test/,"mytest");print}'  
mytest is mytest  
[houchangren@ebsdi-23260-oozie shell]$ echo"test is test" | awk '{sub(/test/,"mytest");print}'  
mytest is test  

[houchangren@ebsdi-23260-oozie shell]$ echo"test is test" | awk '{gsub(/test/,"mytest");print}'
mytest is mytest
[houchangren@ebsdi-23260-oozie shell]$ echo"test is test" | awk '{sub(/test/,"mytest");print}'
mytest is test


 

 

大小写转换



[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ vimawk/translate.awk  
{  
printf("lower:%s\n",tolower($0));  
printf("UPPER:%s\n",toupper($0));  
}  
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/translate.awk data/info.txt  
lower:1.first  is lilei  
UPPER:1.FIRST  IS LILEI  
lower:2.second is liuhai  
UPPER:2.SECOND IS LIUHAI  
lower:3.thrid  is zhangsan  
UPPER:3.THRID  IS ZHANGSAN  
   

[houchangren@ebsdi-23260-oozie shell]$ vimawk/translate.awk
{
printf("lower:%s\n",tolower($0));
printf("UPPER:%s\n",toupper($0));
}
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/translate.awk data/info.txt
lower:1.first  is lilei
UPPER:1.FIRST  IS LILEI
lower:2.second is liuhai
UPPER:2.SECOND IS LIUHAI
lower:3.thrid  is zhangsan
UPPER:3.THRID  IS ZHANGSAN


字符串分割

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$  awk 'BEGIN{info="this is atest";split(info,tA," ");print length(tA);for(k in tA){printk,tA[k];}}'  
4  
4 test  
1 this  
2 is  
3 a  
   

[houchangren@ebsdi-23260-oozie shell]$  awk 'BEGIN{info="this is atest";split(info,tA," ");print length(tA);for(k in tA){printk,tA[k];}}'
4
4 test
1 this
2 is
3 a


字符串重建
 

 

将数组中的元素连接成字符串

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ vimawk/join.awk  
function join (array,n,fs,k,s){  
if( n >= 1 ){  
 s=array[1];  
 for(k=2;k<=n;k++)  
   s=s fs array[k];  
}  
return s;  
}  
   
{  
arr[1]="I";  
arr[2]="am";  
s=join(arr,2," ");  
print s;  
}  
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk -f awk/join.awk  
I am  

[houchangren@ebsdi-23260-oozie shell]$ vimawk/join.awk
function join (array,n,fs,k,s){
if( n >= 1 ){
s=array[1];
for(k=2;k<=n;k++)
s=s fs array[k];
}
return s;
}

{
arr[1]="I";
arr[2]="am";
s=join(arr,2," ");
print s;
}
[houchangren@ebsdi-23260-oozie shell]$ echo"" | awk -f awk/join.awk
I am


 

 

算术函数
 

脚本经常处理报表所以算术函数是必须的。

Awk支持的算术函数

 

 
函数名
说明
atan2( y, x )
返回 y/x 的反正切。
cos( x )
返回 x 的余弦;x 是弧度。
sin( x )
返回 x 的正弦;x 是弧度。
exp( x )
返回 x 幂函数。
log( x )
返回 x 的自然对数。
sqrt( x )
返回 x 平方根。
int( x )
返回 x 的截断至整数的值。
rand( )
返回任意数字 n,其中 0 <= n < 1。
srand( [Expr] )
将 rand 函数的种子值设置为 Expr 参数的值,或如果省略 Expr 参数则使用某天的时间。返回先前的种子值。
 
常用函数

[html]
view plaincopyprint?





//pi的值  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print atan2(0,-1)}'  
3.14159  
//自然对数  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print exp(1)}'  
2.71828  
//exp的反函数  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print log(exp(1))}'  
1  
//平方根  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print sqrt(2)}'  
1.41421  

//pi的值
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print atan2(0,-1)}'
3.14159
//自然对数
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print exp(1)}'
2.71828
//exp的反函数
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print log(exp(1))}'
1
//平方根
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print sqrt(2)}'
1.41421


取整函数



[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print int(100/3)}'  
33  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print 100/3}'  
33.3333  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print int(10.7)}'  
10  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{printf("%f\n",10.7)}'  
10.700000  

[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print int(100/3)}'
33
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print 100/3}'
33.3333
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print int(10.7)}'
10
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{printf("%f\n",10.7)}'
10.700000


 

随机数
 

关于随机数的原理参考:http://blog.csdn.net/johnhany/article/details/8106564

 

 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print rand(); srand();print rand();}'  
0.237788  
0.246611  
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print rand(); srand();print rand();}'  
0.237788  
0.402041  

[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print rand(); srand();print rand();}'
0.237788
0.246611
[houchangren@ebsdi-23260-oozie shell]$ awk'BEGIN{print rand(); srand();print rand();}'
0.237788
0.402041


 

 

 

 

部分信息参考

 

参考:http://www.cnblogs.com/chengmo/archive/2010/10/08/1845913.html

 

 

案例分析

生成数据报表


源数据

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ catdata/sale.txt  
GDD,9041,39,125288  
CGDD,9042,4099,225759  
CGDD,9043,4964.525,415723  
CGDD,9047,1815.238,569063  
CGDD,9053,59,326883  
CGDD,9097,56,651912  
CGDD,9098,39,953235  
CGDD,9017,4099,982040  
CGDD,9019,4964.525,1025987  
CGDD,9018,1815.238,415723  
   
[houchangren@ebsdi-23260-oozie shell]$ catawk/sale.awk  
#/usr/bin/awk -f  
BEGIN{  
FS=",";OFS="\t"  
print"ORG_NAME\tJan\tFeb\tMar\t\tTotal";  
print"---------------------------------------";  
}  
   
{$5 =$2 +$3 +$4}  
{print$1"\t"$2"\t"$3"\t"$4"\t"$5}  
{total2+=$2}  
{total3+=$3}  
{total4+=$4}  
END{  
print"---------------------------------------";  
print "this is Jan total:"total2;  
print "this is Feb total:"total3;  
print "this is Mar total:"total4;  
}  
   
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/sale.awk data/sale.txt  
ORG_NAME        Jan    Feb     Mar             Total  
---------------------------------------  
GDD    9041    39      125288 134368  
CGDD   9042    4099    225759 238900  
CGDD   9043    4964.525        415723 429731  
CGDD   9047    1815.238        569063 579925  
CGDD   9053    59     326883  335995  
CGDD   9097    56      651912 661065  
CGDD   9098    39      953235 962372  
CGDD   9017    4099    982040 995156  
CGDD   9019    4964.525        1025987 1.03997e+06  
CGDD   9018    1815.238        415723 426556  
                                0  
---------------------------------------  
this is Jan total:90475  
this is Feb total:21950.5  
this is Mar total:5691613  

[houchangren@ebsdi-23260-oozie shell]$ catdata/sale.txt
GDD,9041,39,125288
CGDD,9042,4099,225759
CGDD,9043,4964.525,415723
CGDD,9047,1815.238,569063
CGDD,9053,59,326883
CGDD,9097,56,651912
CGDD,9098,39,953235
CGDD,9017,4099,982040
CGDD,9019,4964.525,1025987
CGDD,9018,1815.238,415723

[houchangren@ebsdi-23260-oozie shell]$ catawk/sale.awk
#/usr/bin/awk -f
BEGIN{
FS=",";OFS="\t"
print"ORG_NAME\tJan\tFeb\tMar\t\tTotal";
print"---------------------------------------";
}

{$5 =$2 +$3 +$4}
{print$1"\t"$2"\t"$3"\t"$4"\t"$5}
{total2+=$2}
{total3+=$3}
{total4+=$4}
END{
print"---------------------------------------";
print "this is Jan total:"total2;
print "this is Feb total:"total3;
print "this is Mar total:"total4;
}

[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/sale.awk data/sale.txt
ORG_NAME        Jan    Feb     Mar             Total
---------------------------------------
GDD    9041    39      125288 134368
CGDD   9042    4099    225759 238900
CGDD   9043    4964.525        415723 429731
CGDD   9047    1815.238        569063 579925
CGDD   9053    59     326883  335995
CGDD   9097    56      651912 661065
CGDD   9098    39      953235 962372
CGDD   9017    4099    982040 995156
CGDD   9019    4964.525        1025987 1.03997e+06
CGDD   9018    1815.238        415723 426556
0
---------------------------------------
this is Jan total:90475
this is Feb total:21950.5
this is Mar total:5691613


由于上表数据有点乱,下边修改一下脚本

 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ vimawk/sale.awk  
   
#/usr/bin/awk -f  
BEGIN{  
FS=",";OFS="\t"  
print"ORG_NAME\tJan\tFeb\tMar\t\tTotal";  
print"---------------------------------------";  
}  
   
{$5 =$2 +$3 +$4}  
{printf "%-8s%-10s%-10s%-10s%-20f\n",$1,$2,$3,$4,$5}  
{total2+=$2}  
{total3+=$3}  
{total4+=$4}  
END{  
print "---------------------------------------";  
print "this is Jan total:"total2;  
print "this is Feb total:"total3;  
print "this is Mar total:"total4;  
}  
~  
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/sale.awk data/sale.txt  
ORG_NAME        Jan    Feb     Mar             Total  
---------------------------------------  
GDD    9041      39        125288    134368.000000        
CGDD   9042      4099      225759   238900.000000        
CGDD   9043      4964.525  415723   429730.525000        
CGDD   9047      1815.238  569063   579925.238000        
CGDD   9053      59        326883    335995.000000        
CGDD   9097      56        651912    661065.000000        
CGDD   9098      39        953235    962372.000000        
CGDD   9017      4099      982040   995156.000000        
CGDD   9019      4964.525  1025987  1039970.525000       
CGDD   9018      1815.238  415723   426556.238000        
                                     0.000000             
---------------------------------------  
this is Jan total:90475  
this is Feb total:21950.5  
this is Mar total:5691613  

[houchangren@ebsdi-23260-oozie shell]$ vimawk/sale.awk

#/usr/bin/awk -f
BEGIN{
FS=",";OFS="\t"
print"ORG_NAME\tJan\tFeb\tMar\t\tTotal";
print"---------------------------------------";
}

{$5 =$2 +$3 +$4}
{printf "%-8s%-10s%-10s%-10s%-20f\n",$1,$2,$3,$4,$5}
{total2+=$2}
{total3+=$3}
{total4+=$4}
END{
print "---------------------------------------";
print "this is Jan total:"total2;
print "this is Feb total:"total3;
print "this is Mar total:"total4;
}
~
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/sale.awk data/sale.txt
ORG_NAME        Jan    Feb     Mar             Total
---------------------------------------
GDD    9041      39        125288    134368.000000
CGDD   9042      4099      225759   238900.000000
CGDD   9043      4964.525  415723   429730.525000
CGDD   9047      1815.238  569063   579925.238000
CGDD   9053      59        326883    335995.000000
CGDD   9097      56        651912    661065.000000
CGDD   9098      39        953235    962372.000000
CGDD   9017      4099      982040   995156.000000
CGDD   9019      4964.525  1025987  1039970.525000
CGDD   9018      1815.238  415723   426556.238000
0.000000
---------------------------------------
this is Jan total:90475
this is Feb total:21950.5
this is Mar total:5691613


 

 

多文件联合处理


 

[html]
view plaincopyprint?





   
[houchangren@ebsdi-23260-oozie shell]$ catdata/stuff.txt  
1      zhangsan  
2      lisi  
3      wangwu  
6      maliu  
  
[houchangren@ebsdi-23260-oozie shell]$ catdata/stuff_phone.txt  
13522375325,zhangsan  
18500193250,lisi  
13421320433,wangwu  
18923423443,maliu  
   
[houchangren@ebsdi-23260-oozie shell]$ catawk/stuffJoin.awk  
BEGIN{  
FS="[  |,]";  
OFS=",";  
}  
NR<=FNR{  
a[$2]=$1;  
}  
   
NR>FNR{  
print $1,$2,a[$2]  
}  
   
   
END{}  
   
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/stuffJoin.awk  data/stuff*  
1,zhangsan,13522375325  
2,lisi,18500193250  
3,wangwu,13421320433  
6,maliu,18923423443  
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/stuffJoin.awk  data/stuff.txtdata/stuff_phone.txt  
13522375325,zhangsan,1  
18500193250,lisi,2  
13421320433,wangwu,3  
18923423443,maliu,6  
   

[houchangren@ebsdi-23260-oozie shell]$ catdata/stuff.txt
1      zhangsan
2      lisi
3      wangwu
6      maliu

[houchangren@ebsdi-23260-oozie shell]$ catdata/stuff_phone.txt
13522375325,zhangsan
18500193250,lisi
13421320433,wangwu
18923423443,maliu

[houchangren@ebsdi-23260-oozie shell]$ catawk/stuffJoin.awk
BEGIN{
FS="[  |,]";
OFS=",";
}
NR<=FNR{
a[$2]=$1;
}

NR>FNR{
print $1,$2,a[$2]
}

END{}

[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/stuffJoin.awk  data/stuff*
1,zhangsan,13522375325
2,lisi,18500193250
3,wangwu,13421320433
6,maliu,18923423443
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/stuffJoin.awk  data/stuff.txtdata/stuff_phone.txt
13522375325,zhangsan,1
18500193250,lisi,2
13421320433,wangwu,3
18923423443,maliu,6


 

检验passwd的正确性
 

[html]
view plaincopyprint?





[houchangren@ebsdi-23260-oozie shell]$ catdata/passwd.datafile  
root:x:0:0:root:/root:/bin/bash  
bin:x:1:1:bin:/bin:/sbin/nologin  
daemon:x:2:2:daemon:/sbin:/sbin/nologin  
adm:x:3:4:adm:/var/adm:/sbin/nologin  
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin  
sync:x:5:0:sync:/sbin:/bin/sync  
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown  
halt:x:7:0:halt:/sbin:/sbin/halt  
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin  
news:x:9:13:news:/etc/news:  
new:*:9:13:news:/etc/news:  
halt:x:7:0:halt:/sbin:/sbin/halt:test  
   
[houchangren@ebsdi-23260-oozie shell]$ vimawk/passwd.check.awk  
   
BEGIN{  
FS=":";  
}  
NF!=7{  
printf("line %d,dose not have 7feilds:%s\n",NR,$0);  
}  
$1 !~ /[a-zA-z0-9]/{  
printf("line %d,non alpha and numericuser id :%s\n",NR,$0);  
}  
$2=="*"{  
printf("line %d,no password:%s\n",NR,$0);  
}  
   
END{}  
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/passwd.check.awk data/passwd.datafile  
line 11,nopassword:new:*:9:13:news:/etc/news:  
line 12,dose not have 7feilds:halt:x:7:0:halt:/sbin:/sbin/halt:test  
   

[houchangren@ebsdi-23260-oozie shell]$ catdata/passwd.datafile
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
new:*:9:13:news:/etc/news:
halt:x:7:0:halt:/sbin:/sbin/halt:test

[houchangren@ebsdi-23260-oozie shell]$ vimawk/passwd.check.awk

BEGIN{
FS=":";
}
NF!=7{
printf("line %d,dose not have 7feilds:%s\n",NR,$0);
}
$1 !~ /[a-zA-z0-9]/{
printf("line %d,non alpha and numericuser id :%s\n",NR,$0);
}
$2=="*"{
printf("line %d,no password:%s\n",NR,$0);
}

END{}
[houchangren@ebsdi-23260-oozie shell]$ awk-f awk/passwd.check.awk data/passwd.datafile
line 11,nopassword:new:*:9:13:news:/etc/news:
line 12,dose not have 7feilds:halt:x:7:0:halt:/sbin:/sbin/halt:test


Sed/awk单行脚本
参考:

http://blog.chinaunix.net/uid-20718384-id-3296639.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux shell