awk初步

来源:互联网 发布:超级mac炮 编辑:程序博客网 时间:2024/06/06 02:17

认识awk

Awk是一种小巧的编程语言及命令行工具。它非常适合服务器上的日志处理,主要是因为Awk可以对文件进行操作。它同样使你能够处理数据并转换数
据。
gawk是最新的版本,使用它可以做到数据查找,抽取文本中的数据,创建管道流。
awk有一个主输入循环,次循环反复执行,直到终止条件被触发。我们写好的代码被嵌入到朱输入循环框架中执行。
BEGIN在主输入循环之前执行(未读取输入文件行之前),END则是在主输入循环之后执行。
即AWK程序的三层结构:
BEGIN
主循环
END

代码结构:
Awk脚本的代码结构很简单,就是一系列的模式(pattern)和行为(action):

# commentPattern1 { ACTIONS; }

pattern决定了何时触发事件,action代表处理的方法。

我的第一份awk程序:

#!/bin/awk -f#check all lines has 'I' header./^I/ { print }/*$ cat docI love linuxhello worldI enjoy it.hahahaha.$ ./I.awk docI love linuxI enjoy it.*/

awk将每一个输入文件定义为记录,行中的每一个字符串定义为域,域之间的空格、tab键、其他符号叫做分隔符。
假设有多个tab,可以使用下列指令将其当做一个分隔符:
FS="\t+" (FS="\t"是单个的分隔符)

数据类型
Awk仅有两个主要的数据类型:字符串和数字。
即便如此,Awk的字符串和数字还可以相互转换。字符串能够被解释为数字并把它的值转换为数字值。

如果字符串不包含数字,它就被转换为0.
Awk有数组类型,并且它们是动态的一维关联数组。它们的语法是这样的:var[key] = value 。Awk可以模拟多维数组
awk中还有javascript特性的"23" == 23

awk的部分系统变量:

变量名 意义 $0 所有的域 $n 第n个域 ARGC 命令行参数的数量 ARGV 命令行参数数组 ARCIND 命令行当前文件的位置 CONVFMT 数字转换格式 ENVIRON 环境变量关联数组 ERRNO 最后一个系统错误的描述 FIELDWIDTHS 字段宽度列表,空格键分隔 FILENAME 当前文件名 FNR 浏览文件记录数 NR 当前记录数 FS 字段分隔符 NF 当前记录中的域数量 OFMT 数字的输出格式 OFS 输出域分隔符 ORS 输出记录分隔符 RS 记录分隔符 RLENGTH 由match函数所匹配的字符串长度

awk printf修饰符:

修饰符 意义 - 左对齐 width 域的步长 .prec 小数点右边位数

awk的命令行参数不能被BEGIN{}字段访问。
换一句话说,传参往往和文件联系在一起。

#!/usr/bin/awk -f{    i=0;    while(i < MAX){        print i++;    }}
$ cat > readI lll$ ./arg.sh MAX=5 read01234

awk练习

怎样用shell+awk脚本实现查找/etc/passwd中所有uid>500的记录?

awk 'BEGIN {FS=":"} { if($3>500) print $0; }' red

查看/etc/passwd中所有和root相关的记录

#!/bin/bash#ls all info about root#下面的~表示模糊匹配。awk 'BEGIN { FS=":"} $0~/root/ ' /etc/passwdroot:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologin

查看一个文件中所有的空行,并打印行号。

cat -An doc      1  I love linux$     2  hello world$     3  I enjoy it.$     4  $     5  hahahaha.$     6  $     7  I am excited.$     8  $     9  hahaha.$    10   $    11    $    12  $$ ./black_line.sh 46812all black has 4 lines.
$ cat black_line.sh #!/bin/bash#output all black line numbers and counts.awk 'BEGIN{ x=0;    black=0;  }{     x++;#if($1==""){    if(/^$/){        black++;        print x;    }} END{     printf("all black has %d lines.\n",black); }' doc

将不是以“---->”开头的行打印出来,并重定向一个文件中。

awk '!/^---->/{ print $0 > "read_awk" }' read.txt 

计算sin(0),cos(0),log(1),exp(1),sqrt(2). 保留4位小数。

$ cat calcu.sh #!/bin/bashawk 'BEGIN{ OFMT="%.4f"; gsin = sin(0);gcos = cos(0);glog = log(1);gexp = exp(1);gsqrt = sqrt(2);print gsin,gcos,glog,gexp,gsqrt;}'
./calcu.sh0 1 0 2.7183 1.4142

产生1000内的随机数

#!/bin/bashawk 'BEGIN{srand();  #默认用时间作为种子ans = int(rand()*1000+0.5);print ans;}'

分割字符串。

awk 'BEGIN{info="I love linux and shell.";split(info,elements," ");len=0;for(i in elements){    print i,elements[i];    len++;}printf("length of array is %d.\n",len);}'
$ ./split.sh 1 I2 love3 linux4 and5 shell.length of array is 5.$ cat split.sh 

打印每一行的文字

awk 'BEGIN{while(getline < "jordan"){    count++;    print $0;}printf("the number of Lines is %d\n",count);close("jordan");}'

在下列文本中寻找每一行中“乔丹”第一次出现的位置

这是 乔丹 在 NBA 季 后 赛 当中 的 第一 记 伟大 绝 杀。 在这之前, 乔丹 也 绝 杀 过, 却 没有 任何 一个 如此 关键, 如此 致命, 如此 影响 深远, 如此 让人 刻骨铭心。 这 记 绝 杀 中 投, 在 NBA 史册 中有 个 专属 的 脆生 生的 名字, 就叫“ The Shot”( 那一 投)。这场 生 死战, 乔丹 得到 44 分, 抢 9 个 篮板, 助攻 6 次。 最后 那 两分, 弥补 了 两天 前 第四 场 绝 杀 未成 和 罚球 不进 的 过失。 乔丹 说:“ 这大 概 是我 在 NBA 投进 的 最重要的 一个 球。 主要 是因为, 我 在 紧要  关头, 证明了 自己 是 可信 的。 我 认为 我们 可以 击败 他们, 但是 星期五, 我 错失 了 最后 的 罚球 和 最后 一 投, 害 我们 输 了, 那 是我 在 篮球 场上 最 低落 的 时刻。 就好像 我 高中 时 没 进 得了 校队 那样, 我对 自己 非常 失望, 眼泪 都 出来了。”  

code:

awk 'BEGIN{while(getline < "jordan"){    ret=index($0,"乔丹");    if(ret>0) printf("the index of \"乔丹\"is %d\n",ret);}close("jordan");}'
 ./index.sh the index of "乔丹"is 8the index of "乔丹"is 22

注意:index(str1,str2)如果能找到str2在str1中,那么返回相应的位置,位置是从1开始的。

截取特定区域的文本

awk 'BEGIN{info="I love linux";result=substr(info,8,5);print result;}'

说明: substr(info,8,5)中8是开始的位置,5是截取的长度。同时,info开始的位置标号1.

将文本中的数字全部删除

awk 'BEGIN {     contents="abcd123erf567ghijk";    gsub(/[0-9]/,"",contents);    print contents;}' 

get:

abcderfghijk

注意:
gsub(r,s)在输入文件中用s替换r
gsub(r,s,t)在t中用s替换r
sub(r,s,t)在t中第一次出现的r替换成s
我们将gsub()改成sub():

awk 'BEGIN {     contents="abcd123erf567ghijk";    sub(/[0-9]/,"",contents);    print contents;}'

get

abcd23erf567ghijk
0 0
原创粉丝点击