百度网页搜索部高级工程师 我的微博:http://weibo.com/pengwh85
全部博文(45)
分类: 系统运维
2009-11-17 21:27:21
gawk模式处理语言学习笔记
gawk(GNU awk)工具是一种模式扫描和处理语言,它搜索一个或者多个文件,以查看这些文件中是否存在匹配指定模式的记录(通常是文本行)。每次发现匹配时,它通过执行埈的方式(比如将该记录写到标准输出或者将某个计数器递增)来处理文本。与过程式编程语言相反,gawk属于数据驱动语言:描述想要处理的数据并告诉gawk当它发现这些数据时将要做的事情。
使用gawk可以生成报告或者过滤文本。它在处理时不区分数字和文本,如果将两者混合在一起,gawk通常可以得到正确的答案。
1. 语法
gawk命令行的语法:
gawk [options] [program] [file-list]
gawk [options] -f program-file [file-list]
gawk工具从命令行上指定的文件中或者从标准输入获取输入。使用高级命令getline,用户可以从哪里获取输入以及如何读取等方面有更多选择。使用协进程(coprocess),gawk可以与另一个程序进行交互或者通过网络交换数据。除非将gawk的输出重定向,否则它将被送往标准输出。
2. 参数
program是用户在命令行中所包含的gawk程序。program-file是存放gawk程序的文件的名称。在命令行上使用gawk,就可以编写出简短的gawk程序,而不用创建单独的program-file文件。为了阻止shell将gawk命令解释成shell命令,要将program用单引号引起来。将较长或者较复杂的程序放置在文件中可以减少错误和重复输入。
file-list包含gawk要处理的普通文件的路径名。这些文件就是输入文件。如果用户没有指定file-list,gawk将从标准输入获取输入或者由getline或协进程指定输入。
3. 选项
-f programe-file
-W lint
-W posix
-W traditional
-v var=value
4. 语言基础
gawk程序由一行或者多行文本构成,其中包含一个模式和动作,格式如下:
pattern { action }
1) 模式
用斜杠把正则表达式包装起来,就可以将其作为模式使用。~操作符用于测试某个字段或者变量是否匹配正则表达式。!~操作符用于测试不匹配。可以使用||或&&来组合任何模式。
BEGINT和END:BEGIN和END是两个独特的模式,分别是在gawk开始处理之前和处理完毕之后要执行的命令。
,(逗号):逗号是范围操作符。
2) 动作
如果gawk匹配某个模式,它将执行gawk命令的动作部分所指定的动作。
除非用逗号将print命令中的各项区分开,否则gawk将它们连接起来。逗号使得gawk用输出字段分隔符将各项分隔开。
通过用分号将多个动作隔开,可以在同一行上包含多个动作。
3) 注释
gawk工具不处理以#号开头的程序行中的任何内容。
4) 变量
除了用户变量之外,gawk还维护了程序变量。
-------------------------
$0 当前记录
$1-$n 当前记录中的字段
FILENAME 当前输入文件名(null表示标准输入)
FS 输入字段分隔符
NF 当前记录的字段数目
NR 当前记录的记录编号
OFS 输出字段分隔符(默认为空格符)
ORS 输出记录分隔符(默认为换行符)
RS 输入记录分隔符(默认为换行符)
-------------------------
除了可以在程序中初始化变量之外,还可以在命令行上使用--assign(-v)选项初始化变量。
5) 函数
--------------------------
length(str)
int(num)
index(str1, str2)
split(str, arr, del)
sprintf(fmt, args)
substr(str, pos, len)
tolower(str)
toupper(str)
6) 算术操作符
7) 关联数组
关联数组是gawk最强大的功能之一。这些数组使用字符串作为索引。语法:
array[string] = value
可以将特殊的for结构用于关联数组。语法:
for (elem in array) action
8) printf
语法:
printf "control-string", arg1, arg2, .., argn
转换规格语法:
%[-][x[.y]]conv
其中,-使得printf将参数左对齐,x表示最小字段宽度,.y表示数字中小数点右边的位数。conv指示数值转换的类型。
9) 控制结构
a. if...else
if (condition)
{ commands }
[else
{ commands }]
---------------------------if1------------------------
BEGIN {
nam="sam"
if (nam == "max")
print "nam is max"
else
print "nam is not max, it is ", nam
}
-------------------------------------------------------
$ gawk -f if1
b. while
while (condition)
{ commands }
---------------while1------------------
BEGIN {
n = 1
while (n <= 5)
{
print "2^" n, 2**n
n++
}
}
---------------------------------------
c. for
for (init; condition; increment)
{ commands }
对于关联数组,还可以这样:
for (var in array)
{ commands }
END { for (name in manuf) print name, manuf[name] }
d. break
e. continue
5. case
------------------cars--------------------
plym fury 1970 73 2500
chevy malibu 1999 60 3000
ford mustang 1965 60 10000
volvo s80 1998 102 9850
ford thunddb 2003 15 10500
------------------------------------------
$ gawk '{print}' cars
$ gawk '/ford/' cars
$ gawk '/f/ {print $3,$1}' cars
$ gawk '$1 ~ /f/' cars
$ gawk '$1 ~ /^f/' cars # ^强制在行首进行匹配,而$强制在行末尾或字段末尾进行匹配
$ gawk '$3 == 1999' cars
$ gawk '/chevy/,/ford/' cars
$ gawk '{print length,$0}' cars | sort -n # $0总是包含当前文本行的内容
独立脚本:除了使用-f选项,还可以编写脚本用用户想要运行的命令调用gawk。#!/bin/gawk -f命令用于直接运行gawk工具。
---------------------------
#!/bin/gawk -f
{
{commands}
}
---------------------------
6. gawk高级编程
1) getline:控制输入
2) 协进程:双向I/O 协进程是指与另一个进程并行运行的进程。协进程可用于客户/服务器环境中,搭建SQL前端/后端,或者通过网络与远程系统交换数据。gawk语法通过在启动后台进行的那个程序名称前面添加|&操作符的方式标识协进程。
3) 从网络获取输入
chinaunix网友2009-12-13 17:19:43
哦,进入目录了还是找不到。。。那个命令是不是对呢,filename 应该是个文本文件吧?我看的太少了,还是继续看。。。o(∩_∩)o...
chinaunix网友2009-12-11 11:22:27
你好,我刚看了一点gawk,有这么一个命令 gawk -f filename 我不明白的是,filename这个文件放在什么位置呢?我执行命令的时候找不到文件。。。 谢谢啦。。