awk认真的总结(入门)-AWK程序设计语言

来源:互联网 发布:游戏源码 编辑:程序博客网 时间:2024/06/03 23:41

AWK的结构是模式-动作;可以理解为条件-动作。举个简单的例子:

[root@cuiyf opt]# cat test Beth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18[root@cuiyf opt]# cat test  | awk '$3>0 {print $1,$2*$3}'Kathy 40Mark 100Mary 121Susie 76.5

这里$3>0是条件,顺序是先执行条件再去执行动作。 两者的关系是并的关系。

AWK程序运行结构
awk的运行实际上是按行进行运行的,它是陆续的扫描每一行,找到可以匹配的项{默认的分割符是一个空格}。比如:

[root@cuiyf opt]# awk  '{print $1}'  test BethDanKathyMarkMarySusie

表示每行扫描打印第一个单位$1。

一些简单的了解:
1

全环境打印:
{print} {print $0}

2

打印某些字段:

{print 1,2}

3

计算一行中有多少个字段

{print NR}

例子:

[root@cuiyf opt]# cat 123aa 1bb [root@cuiyf opt]# cat  123  | awk '{print NF}'21

第一行有两个字段,第二行有一个字段。

4

计算和打印

{print 1,2*$3} 数字和字符串相互乘,不报错但是逻辑上不正确。

[root@cuiyf opt]# cat test | awk '{print NR,$0,"is ok !"}'1 Beth 4.00 0 is ok !2 Dan 3.75 0 is ok !3 Kathy 4.00 10 is ok !4 Mark 5.00 20 is ok !5 Mary 5.50 22 is ok !6 Susie 4.25 18 is ok !

5

计算行号

可以使用内置的函数NR进行计算,比如:

[root@cuiyf opt]# cat  test Beth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18[root@cuiyf opt]# cat test | awk '{print NR,$0}'1 Beth 4.00 02 Dan 3.75 03 Kathy 4.00 104 Mark 5.00 205 Mary 5.50 226 Susie 4.25 18

6

字符串和变量一起输出,比如:

[root@cuiyf opt]# cat test | awk '{print NR,$0,"is ok !"}'1 Beth 4.00 0 is ok !2 Dan 3.75 0 is ok !3 Kathy 4.00 10 is ok !4 Mark 5.00 20 is ok !5 Mary 5.50 22 is ok !6 Susie 4.25 18 is ok !

华丽的输出之printf
1

{printf(“total pay for %s is 1, 23)}

执行如下的操作:
%s 是确定$1为字符串模式,%.2f表示取小数点和两位,f浮点类型。这里主要是正则表达式方面的注意一下printf需要有\n。

2

{printf(“%-8s 1,23)}

执行如下的操作:

[root@cuiyf opt]# cat  test |awk '{printf("%-8s $%6.2f\n",$1,$2*$3)}'Beth     $  0.00Dan      $  0.00Kathy    $ 40.00Mark     $100.00Mary     $121.00Susie    $ 76.50这个说明Beth$有8个字符;$到最后一个06个字符

AWK对模式的考虑
模式也可以理解为条件:从以下的几个方面考虑
1
通过比较进行选择

$2*$3>50
[root@cuiyf opt]# cat test   | awk '$2*$3>50 {print $0}'Mark 5.00 20Mary 5.50 22Susie 4.25 18

2
通过文本的内容进行选择

$1=="Mark"
[root@cuiyf opt]# cat test  | awk '$1=="Mark" {printf("%-8s %5.2f %5d\n"),$1,$2,$3}'Mark      5.00    20

3
使用模式组合{或,且,和}{&&;||;!}

$2>5 || $3>20
[root@cuiyf opt]# cat test  | awk '$2>5 || $3>20 {printf("%-10s %5.2f %5d\n",$1,$2,$3)}'Mary        5.50    22

4
BEGIN和END

加上BINGEN的话会在第一行上匹配出对应需要匹配的行,END反之。例子:

[root@cuiyf opt]# cat  test Beth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18[root@cuiyf opt]# cat  test  | awk  'BEGIN{print "SSS AAA NNN"}{print$0 }'SSS AAA NNNBeth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18

5
AWK计算问题
一个动作就是一个语句,每个动作需要使用换行符来区分或者是使用;分隔符来区分。
在计算上不仅是可以使用内置的变量,而且是可以使用自己定义的变量。但是需要知道的是awk不需要申明变量的类型。

计数:
例子:{自创的变量}

[root@cuiyf opt]# cat  test Beth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18 [root@cuiyf opt]# cat  test | awk '$3 > 5 {sum = sum + 1}END{print sum ,"TEXT" "test"}'4 TEXTtest[root@cuiyf opt]# cat  test | awk '$3 > 5 {sum = sum + 1};END{print sum ,"TEXT" "test"}'4 TEXTtest

计算总和和平均数问题

总和计算人数可以使用内置参数NR。例子:

[root@cuiyf opt]# cat test  Beth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18[root@cuiyf opt]# cat test  | awk 'END{print NR}'6

平均数利用所学总和输出
例子:

[root@cuiyf opt]# cat test | awk '{sum = sum + $2*$3}END{printf("%-5d %-5.2f %-5.2f\n", NR,sum,sum/NR)}'6     337.50 56.25

文本的操作与演示:
选出最大值:

[root@cuiyf opt]# cat  test Beth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18[root@cuiyf opt]# cat  test | awk '$2>cui {cui = $2;you = $1}END{print cui,you}'5.50 Mary

字符串的拼接
对于拼接的理解实际上就是将竖行的字符串组成一个行的内容。例子:

[root@cuiyf opt]# cat  test Beth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18[root@cuiyf opt]# cat  test  |awk '{name =name  $1 " "}{print name}'Beth Beth Dan Beth Dan Kathy Beth Dan Kathy Mark Beth Dan Kathy Mark Mary Beth Dan Kathy Mark Mary Susie [root@cuiyf opt]# cat  test  |awk '{name =name  $1 " "}END{print name}'Beth Dan Kathy Mark Mary Susie 

AWK的内建函数

length:主要用来计算字符串中字符的个数。
例子:

[root@cuiyf opt]# awk  '{print $1, length($1) }' test Beth 4Dan 3Kathy 5Mark 4Mary 4Susie 5

行,单词与字符的统计
使用length和NR和NF;例子:

[root@cuiyf opt]# cat  test Beth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18[root@cuiyf opt]# cat  test  | awk '{cui=cui+length($0)+1 ; you=you+NF}END{print NR,cui,you}'6 77 18

其中:NR统计行;cui统计的是字符数;you统计的是单词。{NF 统计一行中有 多少的单词}

控制语句流程

控制语句只能用在动作中 。需要注意不是模式中。

If-Else语句;例子:

[root@cuiyf opt]# [root@cuiyf opt]# cat  test Beth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18[root@cuiyf opt]# cat  test | awk '$2>5{n=n+1;y=$2*$3}{if(n>0) print n,y;else print "no"}'nononono1 1211 121

WHILE语句
while判断当为真的时候,循环继续。

公式:y=a(1+x)^i

[root@cuiyf ~]# cat aaa 1000 0.06 5
[root@cuiyf ~]# cat aaa  | awk '{i=1 }{while(i<=5){printf("\t%.2f\n",$1*(1+$2)^i );i=i+1}}'    1060.00    1123.60    1191.02    1262.48    1338.23

FOR语句实现WHILE语句的功能

[root@cuiyf ~]# cat  aaa | awk '{for (i=1;i<=$3;i=i+1){printf("\t%.2f\n", $1*(1+$2)^i)}}'    1060.00    1123.60    1191.02    1262.48    1338.23

注意一下WHILE和FOR的区别。

数组的简单使用
数组的功能很强大;这里简单的写一个例子实现文件顺序倒写:

[root@cuiyf opt]# cat  test Beth 4.00 0Dan 3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18[root@cuiyf opt]# cat  test | awk '{line[NR]=$0}END{i=NR;while(i>0){print line[i];i=i-1}}'Susie 4.25 18Mary 5.50 22Mark 5.00 20Kathy 4.00 10Dan 3.75 0Beth 4.00 0

+++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++

基本上AWK的简单的介绍算是完毕了 ;总结一下常用的一些用法:

1. 输入行的总行数    END{ print NR }2. 打印第 10 行    NR == 103. 打印每一个输入行的最后一个字段    { print $NF }4. 打印最后一行的最后一个字段    { field = $NF }    END { print field }5. 打印字段数多于 4 个的输入行    NF > 46. 打印最后一个字段值大于 4 的输入行    $NF > 47. 打印所有输入行的字段数的总和    { nf = nf + NF }    END { print nf }8. 打印包含 Beth 的行的数量    /Beth/ { nlines = nlines + 1 }    END { print nlines }9. 打印具有最大值的第一个字段, 以及包含它的行 (假设 $1 总是 正的)    $1 > max { max = $1; maxline = $0 }    END { print max, maxline }10. 打印至少包含一个字段的行    NF > 011. 打印长度超过 80 个字符的行    length($0) > 8012. 在每一行的前面加上它的字段数    { print NF, $0 }13. 打印每一行的第 1 与第 2 个字段, 但顺序相反    { print $2, $1 }14. 交换每一行的第 1 与第 2 个字段, 并打印该行    { temp = $1; $1 = $2; $2 = temp; print }15. 将每一行的第一个字段用行号代替    { $1 = NR; print }16. 打印删除了第 2 个字段后的行    { $2 = ""; print }17. 将每一行的字段按逆序打印    { for (i = NF; i > 0; i = i - 1) printf("%s ", $i)    printf("\n")    }18. 打印每一行的所有字段值之和    { sum = 0    for (i = 1; i <= NF; i = i + 1) sum = sum + $i    print sum    }19. 将所有行的所有字段值累加起来    { for (i = 1; i <= NF; i = i + 1) sum = sum + $i }    END { print sum }20. 将每一行的每一个字段用它的绝对值替换    { for (i = 1; i <= NF; i = i + 1) if ($i < 0) $i = -$i    print    }
0 0
原创粉丝点击