AWK 是一种用于处理文本的编程语言工具。awk经过改进生成的新的版本nawk,gawk,现在默认linux系统下日常使用的是gawk,用命令可以查看正在应用的awk的来源(ls -l /bin/awk )
WK 提供了极其强大的功能:可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。
尽管操作可能有点复杂,但命令的语法始终是:
awk '{pattern + action}' 或者 awk 'pattern {action}'
其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号 ({}) 不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。
awk处理的工作与数据库的处理方式有相同之处,其相同处之一就是awk支持对记录和字段的处理,这也是awk优于二者的原因之一。
内置变量:
内置的字符串函数
gsub(r,s)
|
在整个$0中用s代替r
|
gsub(r,s,t)
|
在整个t中用s替代r
|
index(s,t)
|
返回s中字符串t的第一位置
|
length(s)
|
返回s长度
|
match(s,r)
|
测试s是否包含匹配r的字符串
|
split(s,a,fs)
|
在fs上将s分成序列a
|
sprint(fmt,exp)
|
返回经fmt格式化后的exp
|
sub(r,s)
|
用$0中最左边最长的子串代替s
|
substr(s,p)
|
返回字符串s中从p开始的后缀部分
|
substr(s,p,n)
|
返回字符串s中从p开始长度为n的后缀部分
|
内置的字段函数
$0
: awk变量 $0
保存当前正在处理的行内容 NR
: 当前正在处理的行是 awk 总共处理的行号。 FNR
: 当前正在处理的行在其文件中的行号。 NF
:每行被处理时的总字段数 $NF
: 当前处理行的分隔后的最后一个字段
的值 FS
: 输入行时的字段分隔符,默认空格 OFS
: 输出字段分隔符,默认是一个 空格 ORS
输出记录分隔符, 默认是换行符 awk用0表示整个行(记录)。不同的字段之间是用称作分隔符的字符分隔开的。系统默认的分隔符是空格。awk允许在命令行中用-F re的形式来改变这个分隔符。正是由于这些内置函数的使用,使awk处理字符串的功能更加强大。
使用: 一是通过前面说的内置变量,在awk程序中引用内置变量不需要使用标志符"" ,还有就是自定义变量,awk允许用户在awk程序语句中定义并调用自已的变量,在awk中引用自定义变量必须在它前面加上标志符""。
二是通过命令行
例:显示文本文件mydoc匹配(含有)字符串"sun"的所有行。
awk '/sun/' mydoc
由于显示整个记录(全行)是awk的缺省动作,因此可以省略action项。
awk '/sun/' mydoc
例:下面是一个较为复杂的匹配的示例:
awk '/[Ss]un/,/[Mm]oon/ ' myfile
将会显示所有匹配Sun或sun的行与匹配Moon或moon的行之间的行,并显示到标准输出上。
例:下面的示例显示了内置变量和内置函数length()的使用:
awk 'length($0)>80 {print NR}' myfile
该命令行将显示文本myfile中所有超过80个字符的行号,在这里,用0表示整个记录(行),同时,内置变量NR不使用标志符''。
假设要对linux中的用户进行安全性检查,方法是查看/etc下的passwd文件,检查其中的passwd字段(第二字段)是否为"*",如不为"*",则表示该用户没有设置密码,显示出这些用户名(第一字段)。可以用如下语句实现:
#awk -F : '$2!="*" {printf("%s no password!
",$1)}' /etc/passwd
运算与判断:
awk支持多种运算,这些运算与C语言提供的基本相同:如+、-、*、/、%等等,同时,awk也支持C语言中类似++、--、+=、-=、=+、=-之类的功能。给熟悉c语言的人带来了挺大的方便。
awk 中允许进行多种测试,如常用的==(等于)、!=(不等于)、>(大于)、>=(大于等于)、<=(小于等于)等等,同时,作为样式匹配,还提供了~(匹配于)和!~(不匹配于)判断。
作为对测试的一种扩充,awk也支持用逻辑运算符:!(非)、&&;(与)、||(或)和括号()进行多重判断,这大大增强了awk的功能。
流程控制:
awk提供的完备的流程控制语句类似于C语言。
awk 中两个特别的表达式,BEGIN和END,这两者都可用于pattern中(参考前面的awk语法),提供BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。任何在BEGIN之后列出
的操作(在{}内)将在awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。我举个下面的
例子就好懂了
awk 'BEGIN{print "----开始处理了-----"} {print "ok"} END{print "-----都处理完毕------"}'
-------开始处理了---------
ok
ok
ok
ok
ok
----都处理完毕------------
1 ,if...else语句:
格式:
if(表达式)
语句1
else
语句2
格式中"语句1"可以是多个语句,如果你为了方便awk判断也方便你自已阅读,你最好将多个语句用{}括起来。awk分枝结构允许嵌套,其格式为:
if(表达式1)
{if(表达式2)
语句1
else
语句2
}
语句3
else {if(表达式3)
语句4
else
语句5
}
语句6
当然实际操作过程中你可能不会用到如此复杂的分枝结构,这里只是为了给出其样式而已。
2、while语句
格式为:
while(表达式)
语句
3、do-while语句
格式为:
do
{
语句
}while(条件判断语句)
4、for语句
格式为:
for(初始表达式;终止条件;步长表达式)
{语句}
在awk 的 while、do-while和for语句中允许使用break,continue语句来控制流程走向,也允许使用exit这样的语句来退出。break 中断当前正在执行的循环并跳到循环外执行下一条语句。continue从当前位置跳到循
环开始处执行。对于exit的执行有两种情况:当exit语句不在 END中时,任何操作中的exit命令表现得如同到了文件尾,所有模式或操作执行将停止,END模式中的操作被执行。而出现在END中的exit将导致程序终止。
最后还有调用外部变量:
方法一:awk参数-v(推荐使用,易读)
[root@slave ~]# echo "unix script" |awk -v var="bash" 'gsub(/unix/,var)'
bash script
[root@slave ~]# awk -v user=root -F: '$1 == **user**' /etc/passwd
root:x:0:0:root:/root:/bin/bash
gsub
使 AWK 中的内置函数,功能使搜索替换'gsub(/unix/,var)
中的意思是搜索unix
字符串,替换为 var 变量对应的值
方法二:在双引号的情况下使用
[root@slave ~]# var="bash"
[root@slave ~]# echo "unix script" |awk "gsub(/unix/,"$var")"
bash script
方法三:在单引号的情况下使用
[root@slave ~]# var="bash"
[root@slave ~]# echo "unix script" |awk 'gsub(/unix/,"'"$var"'")'
bash script
结------------------------------------------------------------------------束