awk 教程(主要)

from: http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html

http://www.cnblogs.com/serendipity/archive/2011/08/01/2124118.html

一、 调用方式

1.命令行方式

awk [-F  field-separator]  'commands'  input-file(s)
其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。


2.shell脚本方式
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
可以换成:#!/bin/awk


3.将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)

其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。


二、 命令格式

awk '{pattern + action}' {filenames}  #

任何awk语句都是由模式和动作组成,在一个awk脚本中可能有许多语句。模式部分决定动作语句何时触发及触发事件。动作即对数据进行的操作,如果省去模式部分,动作将时刻保持执行状态

    模式可以是任何条件语句或复合语句或正则表达式,模式包含两个特殊字段BEGIN和END,使用BEGIN语句设置计数和打印头,BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文件开始执行;END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志,有动作必须使用{}括起来

    实际动作在大括号{}内指明,常用来做打印动作,但是还有更长的代码如if和循环looping语句及循环退出等,如果不指明采取什么动作,awk默认打印出所有浏览出的记录

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

示例: awk 'BEGIN {print "being"} {print $1} END {print "end"}' temp  


三、    域和记录:
awk执行时,其浏览标记为$1,$2...$n,这种方法称为域标记。使用$1,$3表示参照第1和第3域,注意这里使用逗号分隔域,使用$0表示使用所有域。例如:
 只打印出第1和第4域 
awk 'BEGIN {print "NAME  GRADE\n----"} {print $1"\t"$4}' temp.txt  
表示打信息头,即输入的内容的第一行前加上"NAME  GRADE\n-------------",同时内容以tab分开

四、 变量

1. 内置变量

awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。

ARGC               命令行参数个数
ARGV               命令行参数排列
ENVIRON            支持队列中系统环境变量的使用
FILENAME           awk浏览的文件名
FNR                浏览文件的记录数
FS                 设置输入域分隔符,等价于命令行 -F选项
NF                 浏览记录的域的个数
NR                 已读的记录数
OFS                输出域分隔符
ORS                输出记录分隔符
RS                 控制记录分隔符

 此外,$0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。

统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:
#awk  -F ':'  '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh
 
使用printf替代print,可以让代码更加简洁,易读
 awk  -F ':'  '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
 
2. 自定义变量

除了awk的内置变量,awk还可以自定义变量。

下面统计/etc/passwd的账户人数
awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
......
user count is  40
count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。

这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0:

awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd

四、 输出函数

print和printf
awk中同时提供了print和printf两种打印输出的函数。
其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。
printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。

五、运算符

1. 算术运算符

    <、<=、==、!=、>=、~匹配正则表达式、!~不匹配正则表达式
    匹配:awk '{if ($4~/ASIMA/) print $0}' temp 表示如果第四个域包含ASIMA,就打印整条
    精确匹配:awk '$3=="48" {print $0}' temp    只打印第3域等于"48"的记录
    不匹配:  awk '$0 !~ /ASIMA/' temp      打印整条不包含ASIMA的记录
    不等于:  awk '$1 != "asima"' temp
   小于:    awk '{if ($1<$2) print $1 "is smaller"}' temp
   设置大小写: awk '/[Gg]reen/' temp      打印整条包含Green,或者green的记录
   任意字符: awk '$1 ~/^...a/' temp    打印第1域中第四个字符是a的记录,符号’^’代表行首,符合’.’代表任意字符
   或关系匹配: awk '$0~/(abc)|(efg)/' temp   使用|时,语句需要括起来
    AND与关系:  awk '{if ( $1=="a" && $2=="b" ) print $0}' temp
  OR或关系:   awk '{if ($1=="a" || $1=="b") print $0}' temp

六、流程控制(与c相同)

1. 条件判断 

if (expression) {
    statement1;
} else if (expression1) {
    statement2;
} else {
    statement3;
}

统计某个文件夹下的文件占用的字节数,过滤4096大小的文件(一般都是文件夹):
ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}' 
[end]size is  8.22339 M

2. 循环语句
awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同。

以上为awk流程控制语句,从语法上面大家可以看到,与c语言是一样的。有了这些语句,其实很多shell程序都可以交给awk,而且性能是非常快的。
break 当 break 语句用于 while 或 for 语句时,导致退出程序循环。
continue 当 continue 语句用于 while 或 for 语句时,使程序循环移动到下一个迭代。
next 能能够导致读入下一个输入行,并返回到脚本的顶部。这可以避免对当前输入行执行其他的操作过程。
exit 语句使主输入循环退出并将控制转移到END,如果END存在的话。如果没有定义END规则,或在END中应用exit语句,则终止脚本的执行。

例1

awk 'BEGIN{ 
total=0;
for(i=0;i<=100;i++)
{
    total+=i;
}
print total;
}'

例2:

awk 'BEGIN{ 
test=100;
total=0;
while(i<=test)
{
    total+=i;
    i++;
}
print total;
}'

七、数组

  因为awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。

显示/etc/passwd的账户
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
0 root
1 daemon
2 bin
3 sys
4 sync
5 games
......
这里使用for循环遍历数组


 八、awk内置字符串函数:
gsub(r,s)           在整个$0中用s替代r
awk 'gsub(/name/,"xingming") {print $0}' temp
gsub(r,s,t)         在整个t中用s替代r
index(s,t)          返回s中字符串t的第一位置
awk 'BEGIN {print index("Sunny","ny")}' temp     返回4
length(s)           返回s的长度
match(s,r)          测试s是否包含匹配r的字符串
awk '$1=="J.Lulu" {print match($1,"u")}' temp    返回4
split(s,a,fs)       在fs上将s分成序列a
awk 'BEGIN {print split("12#345#6789",myarray,"#")"'
返回3,同时myarray[1]="12", myarray[2]="345", myarray[3]="6789"

sprint(fmt,exp)     返回经fmt格式化后的exp
sub(r,s)   从$0中最左边最长的子串中用s代替r(只更换第一遇到的匹配字符串)
substr(s,p)         返回字符串s中从p开始的后缀部分
substr(s,p,n)       返回字符串s中从p开始长度为n的后缀部分



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值