免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1274 | 回复: 0
打印 上一主题 下一主题

awk使用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-06-27 09:14 |只看该作者 |倒序浏览
边学awk,边整理吧。非常感谢各个无私的网友们,提供了那么多例子还有文档。
awk是啥东东我就不用多说了吧,现在开始说用法,有浅入深。
awk基本调用方式
a)         命令行   
像输指令一样,输入一大堆长长的命令。虽然最简单,但是对于长指令,忒累了,还是换吧。
b)        –f 指定文件
可以将其写在一个文件里,用-f 指定
#awk –f test.awk filename
c)        命令解释器
有点像写shell脚本。除了开头不一样,下面格式基本一致,也是#是注释。
#!/bin/awk –f
。。。。。。。

几个简单的概念
·         Awk 有"file"文件, "record"记录, and "field"域的概念.
一个file包括多个record,record单位默认是行
Awk 每次处理一条record
每条记录存在多个field,默认是由任何数目的空格或TAB来分割
Field 1 用$1表示, field 2用$2, 等等. $0表示整条record.
在awk中有几个固定变量:
ARGC 命令行变元个数
ARGV 命令行变元数组
FILENAME 当前输入文件名
FNR 当前文件中的记录号
FS 输入域分隔符,默认为一个空格
RS 输入记录分隔符
NF 当前记录里域个数
NR 到目前为止记录数
OFS 输出域分隔符
ORS 输出记录分隔符

这几个变量在awk中直接用,下面看例子吧,本人文笔不行,效果一定要大家自己实践哦。哈

awk功能
基本输出功能
Ø      awk '{print $0}' filename              表示输出所有行
Ø      awk '{print $2,$1}' filename 输出每行的第二个filed和第一个field


数学/比较功能
Ø         awk '$1 > $2 {print $1,$2,$1-$2}' filename  如果filed 1 大于 field 2,则将输出field1, field2, field1-field2的值
其实awk支持普通的数学比较符,主要有:
==;       !=;       ; >; ;     >=;     ?:
还有数学操作符
       +; -;  *;  %;  +=;-=;%=;*=; ++ ……..
布尔操作符
       !;  &&;     ||;
大家学过C语言,应该很明白这些东东咋用吧。
Ø         awk '$1=="foo"{print $2}' filename
Ø         awk '$2 >5 && $2
注意,如果是字符串,需要使用双引号括起来。

使用正则表达式功能
Ø         awk '/101/'  filename     显示文件中包含101的匹配行。
Ø         awk '/1/,/5/' filename            这个比较有意思,显示包含1的行和包含5的行之间的所有行,包括这两行。注意包含1的意思,12也是包含1的,我在这里绕了半天。如果只找到了包含1的行,而没有包含5的行,则从包含1的行输出到文件结尾。
Ø         awk '/101/ {print $1 $2}' filename      显示文件file的匹配行的第一、二个域,但显示中间没有分隔符。
Ø         awk ‘/[sS]un/[mM]on/’ filename

BEGIN END
awk BEGIN{…}  {…..}    END{…}  filename
任何在BEGIN之后列出的操作将在awk扫描输入前执行
任何在END之后列出的操作将在awk扫描完成后执行。
当然,BEGIN和END可以分别使用。
Ø         awk ‘BEGIN { OFS="%"} {print $1,$2}’ filename     
通过设置输出分隔符(OFS="%")修改输出格式。
Ø         awk   'BEGIN { max=100;print "max="max} {max=($1 >max ?$1:max); print $1,"Now max is "max}' filename
               取得文件第一个域的最大值。
(表达式1?表达式2:表达式3 相当于:
   if (表达式1)
       表达式2
   else
       表达式3
   awk '{print ($1>4 ? "high "$1: "low "$1)}' filename

Ø         awk '/tom/ {count++;} END {print "tom was found "count" times"}' filename
END表示在所有输入行处理完后进行处理

命令行模式下的 -F
命令行下awk的格式为:
awk [ -F re] [parameter...] ['prog'] [-f progfile][in_file...]
参数说明:
-F re:允许awk更改其字段分隔符。
parameter: 该参数帮助为不同的变量赋值。
'prog': awk的程序语句段。这个语句段必须用单拓号:'和'括起,以防被shell解释。这个程序语句段的标准形式为:
'pattern {action}'
其中pattern参数可以是正则表达式中的任何一个,它可以使用语法/re/再加上一些样式匹配技巧构成。与sed类似,你也可以使用","分开两样式以选择某个范围。
action参数总是被大括号包围,它由一系统awk语句组成,各语句之间用";"分隔。awk解释它们,并在pattern给定的样式匹配的记录上执行其操作。与shell类似,你也可以使用“#”作为注释符,它使“#”到行尾的内容成为注释,在解释执行时,它们将被忽略。你可以省略pattern和action之一,但不能两者同时省略,当省略pattern时没有样式匹配,表示对所有行(记录)均执行操作,省略action时执行缺省的操作――在标准输出上显示。

awk -F "|" '{print $1}'  filename 按照新的分隔符“|”进行操作
awk -F '[][]' '{print $1}' filename  按照正则表达式的值做为分隔符,这里代表[、]

变量
awk可以使用变量,变量默认初始化为0或者空字符串(使用0还是空字符串,根据使用类型决定)。
Ø         awk '/tom/ {wage=$2+$3; printf wage}' filename  找到匹配行后为变量wage赋值并打印该变量。
Ø         awk ‘{print $1,$NF }' filename            输出第一个和最后一个域值
Ø         awk '{for(i=1;i             输出每个域值
Ø         awk '/tom/ {count++;}  END {print "tom was found "count" times"}' filename  END表示在所有输入行处理完后进行处理(count默认初始化为0)。
Ø         awk '{x=1.0/NR; print x,sin(x)/x;}'         一直回车看看吧:)

数组
awk可以使用数组,下面是一个脚本的例子;还可以使用多维数组,那个就稍微有点复杂了。就不在这里介绍了。
#!/usr/bin/awk -f{for(i=1;i      END{for(word in freq) print word, freq[word]  }

内置函数
很多好用的内置函数,直接看附录吧。
例子:
Ø         awk 'gsub(/\$/,"");gsub(/,/,""); cost+=$4;  END {print "The total is $" cost>"filename"}'  filename
gsub函数用空串替换$和,再将结果输出到filename中。

流程控制语句
像if else, while, do while 都可以在awk里使用; next的意思是执行下一条记录,功能与C语言中的continue基本一样,next导致这个记录的任何额外匹配模式被忽略。

Ø         awk '{gsub(/\$/,"");gsub(/,/,""); if ($4>3000) next; else c4+=$4; }
    END {printf  "c4=[%d]\n",c4}"' filename
自定义函数
awk函数的定义方法如下:
function 函数名(参数表){
函数体
}
在awk中调用函数比较简单,其方法与C语言相似,但awk比C语言更为灵活,它不执行参数有效性检查。换句话说,在你调用函数时,可以列出比函数预计(函数定义中规定)的多或少的参数,多余的参数会被awk所忽略,而不足的参数,awk将它们置为缺省值0或空字符串,具体置为何值,将取决于参数的使用方式。
awk函数有两种返回方式:隐式返回和显式返回。当awk执行到函数的结尾时,它自动地返回到调用程序,这是函数是隐式返回的。如果需要在结束之前退出函数,可以明确地使用返回语句提前退出。方法是在函数中使用形如:return 返回值 格式的语句。
例:下面的例子演示了函数的使用。在这个示例中,定义了一个名为print_header的函数,该函数调用了两个参数FileName和PageNum,FileName参数传给函数当前使用的文件名,PageNum参数是当前页的页号。这个函数的功能是打印(显示)出当前文件的文件名,和当前页的页号。完成这个功能后,这个函数将返回下一页的页号。
Ø         awk 'BEGIN{pageno=1;file=FILENAME
pageno=print_header(file,pageno);                                               
printf("当前页页号是:%d",pageno);}

#定义函数print_header
function print_header(FileName,PageNum){
printf("%s %d",FileName,PageNum); >PageNum++;return PageNUm;
}
}' myfile
执行这个程序将显示如下内容:
myfile 1
当前页页号是:2

附录:
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~re x匹配正则表达式re?
x!~re x不匹配正则表达式re?
4.awk的操作符(按优先级升序排列)
= 、+=、 -=、 *= 、/= 、 %=
||
&&
> >= 字符串连结,'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 下标分隔符 "34"
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日以来经过的时间(按秒计算)


参考文献
1.
http://www.cs.hmc.edu/qref/awk.html
2. Unix awk使用手册(第二版)
3. http://www.chinaunix.net/jh/24/691456.html


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/67707/showart_1013911.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP