Chinaunix首页 | 论坛 | 博客
  • 博客访问: 239172
  • 博文数量: 59
  • 博客积分: 2661
  • 博客等级: 少校
  • 技术积分: 732
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-24 11:54
文章分类

全部博文(59)

文章存档

2013年(1)

2012年(8)

2011年(17)

2010年(33)

我的朋友

分类:

2010-10-08 11:25:53

awk

  • awk语言的最基本功能是在文件或字符串中基于指定规则浏览和抽取信息。 awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。主要用途是格式化报文或者从一个大的文本文件中抽取数据包。
  • awk操作数据时,两个记录分隔符之间的数据称为一个记录,默认记录分隔符为换行(即每行为一个记录)。每一记录在两个域分隔符之间的数据称为一个域,默 认域分隔任为空格(即每个单词为一个域)。在一个记录中的域依次用域标识符标识为$1, $2...$n。可以通过域标识符对所有记录的文本数据进行操作。其中$0代表所有的域。
  • 有三种方式调用awk,
    • 命令行方式:awk [-F field-separator] 'commands' input-file(s) 其中-F选项是可选的,awk默认使用空格做为域分隔符。
    • 脚本文件方式:将所有的awk命令插入一个文件,用awk命令解释器作为脚本的首行,并使脚本可运行。
    • 脚本和命令行方式:将awk命令写入脚本文件,将该脚本作为awk -f awk-script-file input-file(s)。
  • awk语句由模式和动作组成。模式部分决定动作语句何时触发及触发事件。动作即对数据的操作,由{}包括起来。
  • awk可以使用正则表达式作为匹配条件由/包括起来。
  • awk支持的正则表达式的元字符包括:\ ^ $ . [] | () * + ?。其中之+ ?只适用于awk不适用于grep或sed
		+ 使用+匹配一个或多个字符。
?前面匹配模式出现频率为一次或者没有。
  • awk模式可以是复合语句或者正则表达式,awk模式中有两个特殊字段:BEGIN(设置计数和打印头),END(打印文本总数和结束状态标志)。
  • awk模式语句相当于动作中的条件语句。如:awk '$3!~/pattern/{print 0}' file相当于awk '{if($3!~/pattern) print $0}' file
  • 单独使用awk模式语句时,相当于awk模式语句再加上print $0。如awk '$0 ~/pattern/' file相当于awk '$0~/pattern/{print $0}' file和awk '{if($0~/pattern/)print $0}' file
  • awk同样支持关系正则表达式匹配即:'|'意味着匹配|两边正则表达式其中之一。当使用或时,必须将正则表达式用()包括起来。如:awk '$0~/(pattern1|pattern2)/' file。
  • 复合表达式为模式间或者条件语句间通过&&(且)、||(或)、!(非)结合起来。
		&& 两边条件为真,如:awk '$0 ~/pattern/&&$3=="string"{print $1}' file
|| 两边条件之一为真,如:awk '{if($0~/pattern/||$3=="string") print $1}' file
  • awk内置变量:
		ARGC	:命令行参数个数,或者传入脚本的参数个数。
ARGV :参数排列数组,第n个参数记录为ARGV[n-1]。
ENVIRON :系统设置的环境变量。单独环境变量用实际变量名,如ENVIRON["EDITOR"]="Vi"。
FILENAME:awk实际操作的输入文件,当awk同时处理多个文件时,代表正在被处理的文件。
FNR :当前文件操作的记录数。值小于等于NR(所有操作记录的总数)。
NR :所有操作记录的总数。
NF :当前记录的域数。&NF可以获取,最后一个域的值。
FS :输入域分隔符,和命令中-F选项一样,可以进行设置,默认为空格。
OFS :输入出域分隔符,可以进行设置,默认为空格。
RS :输入记录分隔符,可以进行设置,默认为换行符(\n)。
ORS :输出记录分隔符,可以进行设置,默认为换行符(\n)。
  • awk基本数据操作
    • 设置输入域(awk在记录中读取的域)到域变量名。设置方式为name=$n。如:ls -l|awk '{name=$NF; print name}'
    • 在BEGIN中设置变量并对变量赋值。 在实际操作的awk模式和动作中,可以使用此变量。如:ls -l|awk 'BEGIN{size=10; print "name\tsize"}($5>size){print $NF"\t"$5}'
    • 可以修改域值。修改域值只是修改保存在缓存里的awk复本,没有修改原文件的数据。如:ls -l|awk '($5>10){$1="right"; $5=20; print $0}'
    • 创建新的输出域。可以使用新的域标识符,也可以创建一个新域变量名使用。如:ls -l|awk '($5>10){csize=($5*512);print $0, csize}'
  • awk字符串操作
    • gsub(r,s,t):在整个t中用s替代所有的r,会改变域值及awk数据复本。如果没有t参数,则在整个$0中。如:echo "Seven Xia" | awk '{gsub("X", "xXxX", $2);print $0}'
    • sub(pattern, s, STR):将正则表达式pattern第一次的匹配替换为s,会改变域值及awk数据复本。如果没有STR参数,则在整个$0中。匹配原则为最大匹配。 如:echo "Seven Xia" | awk '{sub(/S.*/, "Seven"); print $0}'
    • index(s, t):返回s中第一次在t中出现的位置。如:echo "Seven Xia"|awk '{n = index(735035, 35); print n, $0}'
    • match(s, pattern):返回s中第一次匹配pattern的位置。如果没有匹配则返回0。如:echo "Seven Xia"|awk '{n=match($0, /[A-Z]/); print n}'
    • length(st):返回st的长度。如:echo "Seven Xia"|awk '{n=length($0); print n, $0}'
    • substr(s, p, n):返回s中从p开始n个字符部分,如是参数n大于剩余字符或者参数n不存在,则返回s中从p到结束部分。如:echo "Seven Xia" | awk '{left = substr($0, 3, 9); print $0, "\t", left}'
    • split(s, a, fs):以fs为标志将s分隔到数组a。如awk '{split("123#456#789", myarray, "#"); print myarray[1], myarray[2], myarray[3]}'
  • awk格式化字符串输出。awk的printf函数和c的printf函数格式化字符串很相似,以%开始,以决定转换类型的字符结束,中间包括三种修饰符:%[flags][fldwidth][precision]convtype
    • flags包括:+(总是显示符号),-(左对齐字段)
    • fldwidth:字段最小宽度
    • precision:前加.表示浮点型精度。
    • 例:echo "Seven Xia" | awk '{printf("%-20s, %s, %+10d, %10.10f\n", $1, $2, 30, 30.3)}'
  • 可以在命令行中设置变量及值,然后传入awk中。awk '($1>NUM){print $0}' AGE=20 file
  • awk执行脚本:
    • awk脚本中,第一行一定是#!/bin/awk来说明脚本文件的解释器。
    • 在写脚本时,BEGIN和END后面要紧跟着{,否则会出错。
    • 命令行用-F选项指定域分隔符,但在脚本语句中,只能在BEGIN时,对FS变量进行设置。如FS=":"
  • awk数组使用前,不需要定义,也不需要指定数组元素个数。访问数组的循环是:for(element in array) print array[element],其中elment即数组的标识,可以不是数字。
阅读(1533) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~