Chinaunix首页 | 论坛 | 博客
  • 博客访问: 89714
  • 博文数量: 41
  • 博客积分: 1649
  • 博客等级: 上尉
  • 技术积分: 415
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-20 17:02
文章分类

全部博文(41)

文章存档

2011年(4)

2010年(1)

2009年(14)

2008年(2)

2006年(6)

2005年(14)

我的朋友

分类:

2005-07-27 16:13:06

awk脚本    条件操作符  内置变量   内置的字符串函数 

awk中使用的屏蔽序列 输出函数printf

向一行a w k命令/a w k脚本传值: 

awk脚本
在命令中调用a w k时,a w k脚本由各种操作和模式组成。
如果设置了- F选项,则a w k每次读一条记录或一行,并使用指定的分隔符分隔指定域,但如果未设置- F选项,a w k假定空格为域分隔符,并保持这个设置直到发现一新行。当新行出现时,a w k命令获悉已读完整条记录,然后在下一个记录启动读命令,这个读进程将持续到文件尾或文件不再存在。

参照表,a w k每次在文件中读一行,找到域分隔符(这里是符号#),设置其为域n,直至一新行(这里是缺省记录分隔符),然后,划分这一行作为一条记录,接着a w k再次启动下一行读进程。

域1 分隔符 域2 分隔符 域3 分隔符 域4及换行
P. B u n n y (记录1 ) # 0 2 / 9 9 # 4 8 # Yellow
J . Tr o l l (记录2 ) # 0 7 / 9 9 # 4 8 4 2 # Brown-3

• 确保整个a w k命令用单引号括起来。
• 确保命令内所有引号成对出现。
• 确保用花括号括起动作语句,用圆括号括起条件语句。
• 可能忘记使用花括号,也许你认为没有必要,但a w k不这样认为,将按之解释语法

a w k条件操作符
< 小于 > = 大于等于    < = 小于等于   ~ 匹配正则表达式   = = 等于     !~ 不匹配正则表达式      != 不等于

为使一域号匹配正则表达式,使用符号‘~’后紧跟正则表达式,awk '$0 ~ /Brown/' grade.txt

要使字符串精确匹配:    e. g.  awk '$3=="48" {print$0}' grade.txt      awk '{if($3=="48") print$0}' grade.txt

有时要浏览信息并抽取不匹配操作的记录,与~相反的符号是!~,意即不匹配。

awk内置变量
a w k有许多内置变量用来设置环境信息。这些变量可以被改变。表9 - 3显示了最常使用的一些变量,并给出其基本含义。

awk内置变量
A R G C 命令行参数个数
A R G V 命令行参数排列
E N V I R O N 支持队列中系统环境变量的使用
FILENAME a w k浏览的文件名
F N R 浏览文件的记录数
F S 设置输入域分隔符,等价于命令行- F选项
N F 浏览记录的域个数
N R 已读的记录数
O F S 输出域分隔符
O R S 输出记录分隔符
R S 控制记录分隔符

A R G C支持命令行中传入a w k脚本的参数个数。A R G V是A R G C的参数排列数组,其中每一元素表示为A R G V [ n ],n为期望访问的命令行参数。

E N V I R O N 支持系统设置的环境变量,要访问单独变量,使用实际变量名,例如E N V I R O N [“E D I TO R”] =“Vi”。

F I L E N A M E支持a w k脚本实际操作的输入文件。因为a w k可以同时处理许多文件,因此如果访问了这个变量,将告之系统目前正在浏览的实际文件。

F N R支持a w k目前操作的记录数。其变量值小于等于N R。如果脚本正在访问许多文件,每一新输入文件都将重新设置此变量。

F S用来在a w k中设置域分隔符,与命令行中- F选项功能相同。缺省情况下为空格。如果用逗号来作域分隔符,设置F S = ","。

N F支持记录域个数,在记录被读之后再设置。

O F S允许指定输出域分隔符,缺省为空格。如果想设置为#,写入O F S = " # "。

O R S为输出记录分隔符,缺省为新行( n)。

R S是记录分隔符,缺省为新行( n )。


显示其目录: echo $PWD | awk -F/ ' {print $NF}'        显示文件名:    echo "/usr/local/etc/rc.sybase" | awk -F/ '{print $NF}'

修改数值域取值:          awk '{if($1=="L.Tansl") $4=$4"2";print $0}' grade.txt

只显示修改记录
上述例子均是对一个小文件的域进行修改,因此打印出所有记录查看修改部分不成问题,但如果文件很大,记录甚至超过1 0 0,打印所有记录只为查看修改部分显然不合情理。在模式后面使用花括号将只打印修改部分。取得模式,再根据模式结果实施操作,可能有些抽象,现举一例,只打印修改部分。注意花括号的位置。

awk '{if($1=="J.Troll") {$1="J.L.Troll"; print $1}}' grade.txt

文件长度相加
在目录中查看文件时,如果想快速查看所有文件的长度及其总和,但要排除子目录,使用ls -l命令,然后管道输出到a w k,a w k首先剔除首字符为d(使用正则表达式)的记录,然后将文件长度列相加,并输出每一文件长度及在E N D部分输出所有文件的长度。文件长度是第5列,文件名是第9列。下面的正则表达式表明必须匹配行首,并排除字符d,表达式为^ [ ^ d ]。 使用此模式打印文件名及其长度,然后将各长度相加放入变量t o t中。

ls -l | awk '/^[^d]/ {print $9" "$5} {tot+=$5} END {print "total KB:" tot}'

内置的字符串函数

代码:
awk内置字符串函数
g s u b ( r, s ) 在整个$0中用s替代r   e.g.   awk 'gsub(/4842/,4899){print $0}' grade.txt
g s u b ( r, s , t ) 在整个t中用s替代r  
i n d e x ( s , t ) 返回s中字符串t的第一位置    e.g.    awk 'BEGIN {print index("Bunny","ny")}' grade.txt
l e n g t h ( s ) 返回s长度
m a t c h ( s , r ) 测试s是否包含匹配r的字符串 e.g. awk 'BEGIN{print match("ANCD",/D/)}'   awk '$1=="J.Lulu" {print match($1,"u")}' grade.txt
s p l i t ( s , a , f s ) 在f s上将s分成序列a  e.g.      awk 'BEGIN {print split("123#456#789",myarray,"#")}'   myarray[1]=123 myarray[2]=456 myarray[3]=789
s p r i n t ( f m t , e x p ) 返回经f m t格式化后的e x p
s u b ( r, s , str) 用str中最左边最长的子串代替s     e.g.      awk '$1=="J.Troll" sub(/26/,"29",$0)' grade.txt
s u b s t r ( s , p ) 返回字符串s中从p开始的后缀部分
s u b s t r ( s , p , n ) 返回字符串s中从p开始长度为n的后缀部分  e.g.  awk '$1=="L.Tansl" {print substr($1,1,3)}' grade.txt
 


awk中使用的屏蔽序列
b 退格键
t t a b键
f 走纸换页
d d d 八进制值
n 新行
c 任意其他特殊字符,例如 为反斜线符号
r 回车键

awk输出函数printf
a w k提供函数p r i n t f,拥有几种不同的格式化输出功能。例如按列输出、左对齐或右对齐方式。每一种p r i n t f函数(格式控制字符)都以一个%符号开始,以一个决定转换的字符结束.转换包含三种修饰符。p r i n t f函数基本语法是p r i n t f([格式控制符],参数),格式控制字符通常在引号里。

printf修饰符


代码:
- 左对齐
Wi d t h 域的步长,用0表示0步长
. p r e c 最大字符串长度,或小数点右边的位数
表9-7 awk printf格式
% c A S C I I字符
% d 整数
% e 浮点数,科学记数法
% f 浮点数,例如(1 2 3 . 4 4)
% g a w k决定使用哪种浮点数转换e或者f
% o 八进制数
% s 字符串
% x 十六进制数


e.g   awk '{printf "%-15s %s ",$1,$3}' grade.txt

向一行a w k命令传值:    awk '{if ($5

 向a w k脚本传值:          向a w k脚本传值与向a w k一行命令传值方式大体相同,格式为: awk script_file var=value input_file

数组使用前,不必定义,也不必指定数组元素个数。经常使用循环来访问数组。下面是一种循环类型的基本结构:For (element in array ) print array[element]

阅读(959) | 评论(5) | 转发(0) |
给主人留下些什么吧!~~