Linux 命令 grep sed awk : awk

1.awk 是什么?

    The basic function of awk is to search files for lines (or other units of text) that contain certain patterns. When a line matches one of the patterns, awk performs specified actions on that line. awk continues to process input lines in this way until it reaches the end of the input files.
    When you run awk, you specify an awk program that tells awk what to do. The program consists of a series of rules (it may also contain function definitions, an advanced feature that we will ignore for now; see User-defined). Each rule specifies one pattern to search for and one action to perform upon finding the pattern.  

总的来说 “awk”其实是一种文本处理语言,至于处理那些文本?怎么处理?则就是你要指定的rules。

以前就简简单单的认为awk 就是分析分析linux命令输出的工具,看来还是too young 。

2.awk 怎么用?

1.awk命令行,你可以象使用普通UNIX命令一样使用awk,在命令行中你也可以使用awk程序设计语言,虽然awk支持多行的录入,但是录入长长的命令行并保证其正确无误却是一件令人头疼的事,因此,这种方法一般只用于解决简单的问题。当然,你也可以在shell script程序中引用awk命令行甚至awk程序脚本。 

2.使用-f选项调用awk程序。awk允许将一段awk程序写入一个文本文件,然后在awk命令行中用-f选项调用并执行这段程序。具体的方法我们将在后面的awk语法中讲到。  

3.awk的用法举例

先说awk 语言,然后再说 awk的命令行的方式 。awk命令行方式就是把awk脚本放在命令行中去,这样就比较方便每次操作。

a.awk 脚本:

$awk -f action.awk test.log

ps:
- action.awk awk脚本
- test.log 待处理文件

我们需要注意两个关键词BEGIN和END。

- BEGIN{ 这里面放的是执行前的语句 }
- END {这里面放的是处理完所有的行后要执行的语句 }
- {这里面放的是处理每一行时要执行的语句}

假设有这么一个文件(学生成绩表):

$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

我们的awk脚本如下:

$ cat cal.awk
#!/bin/awk -f
#运行前
BEGIN {
    math = 0
    english = 0
    computer = 0

    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#运行中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}

我们来看一下执行结果:

$ awk -f cal.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  TOTAL:       319      393      350
AVERAGE:     63.80    78.60    70.00

总得来说就是先设置变量,然后读取每行数据(也可以是几行),操作数据,输出。

awk内建变量:

变量描述
$n当前记录的第n个字段,字段间由FS分隔(默认是空格,和Tab)
$0输出所有的列
ARGC命令行参数的数目
ARGIND命令行中当前文件的位置(从0开始算)
ARGV包含命令行参数的数组
CONVFMT数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO最后一个系统错误的描述
FIELDWIDTHS字段宽度列表(用空格键分隔)
FILENAME当前文件名
FNR同NR,但相对于当前文件
FS字段分隔符(默认是任何空格)
IGNORECASE如果为真,则进行忽略大小写的匹配
NF当前记录中的字段数(改行的第几列)
NR当前记录数(第几行)
OFMT数字的输出格式(默认值是%.6g)
OFS输出字段分隔符(默认值是一个空格)
ORS输出记录分隔符(默认值是一个换行符)
RLENGTH由match函数所匹配的字符串的长度
RS记录分隔符(默认是一个换行符)
RSTART由match函数所匹配的字符串的第一个位置
SUBSEP数组下标分隔符(默认值是/034)

内置变量说明:

$ awk 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
log.txt    2    1         5    1
log.txt    2    2         5    2
log.txt    2    3         3    3
log.txt    2    4         4    4
$ awk -F\' 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
log.txt    2    1    '    1    1
log.txt    2    2    '    1    2
log.txt    2    3    '    2    3
log.txt    2    4    '    1    4
# 输出顺序号 NR, 匹配文本行号
$ awk '{print NR,FNR,$1,$2,$3}' log.txt
---------------------------------------------
1 1 2 this is
2 2 3 Are you
3 3 This's a test
4 4 10 There are
# 指定输出分割符
$  awk '{print $1,$2,$5}' OFS=" $ "  log.txt
---------------------------------------------
2 $ this $ test
3 $ Are $ awk
This's $ a $
10 $ There $

awk运算符:

运算符描述
= += -= = /= %= ^= *=赋值
?:C条件表达式
|
&&逻辑与
~ ~!匹配正则表达式和不匹配正则表达式
< <= > >= != ==关系运算符
+ -加,减
* / &乘,除与求余
+ - !一元加,减和逻辑非
^ *求幂
++ –增加或减少,作为前缀或后缀
$字段引用
in数组成员

b.awk 命令行:
熟悉了awk 脚本后,再来用awk 命令行工具就很容易了。就是在脚本内容比较少的时候把所有的东西放在一行中就OK啦。

awk [选项参数] 'script' var=value file(s)
选项参数说明:
1.-F fs or --field-separator fs
指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
2.-v var=value or --asign var=value
赋值一个用户定义变量。

基本用法:

$cat test.log
2 this is a test
3 Are you like awk
This's a test
10 There are orange,apple,mongo

# 每行按空格或TAB分割,输出文本中的1、4项
 $ awk '{print $1,$4}' test.log
 ---------------------------------------------
 2 a
 3 like
 This's
 10 orange,apple,mongo
 # 格式化输出
 $ awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
 ---------------------------------------------
 2        a
 3        like
 This's
 10       orange,apple,mongo

$cat tt.log
2016-11-15 15:18:53 flow*netflow-udp*0006a030*1013400.0*1015100.0
2016-11-15 15:19:23 req*allocate*0006a030*15.0*0.0
2016-11-15 15:19:23 req*auth*0006a030*125.0*30.0
2016-11-15 15:19:23 req*binding*0006a030*0.0*0.0
2016-11-15 15:19:23 req*channelbind*0006a030*20.0*0.0
2016-11-15 15:19:23 req*refresh*0006a030*35.0*0.0
2016-11-15 15:19:32 online*turn_delay_time*0006a030*0.0
2016-11-15 15:19:32 online*turn_lost_packs_rates*0006a030*0.0
2016-11-15 15:19:35 online*turn_delay_time*0006a030*0.0
2016-11-15 15:19:35 online*turn_lost_packs_rates*0006a030*0.0

#以 "*"为分隔符,统计规定时间段内 最后两列的和
$cat tt.log |awk '$2>"15:19:20"&&$2<"15:19:35"' | awk -F"[*]" '{for(i=0;i<2;i++){sum[i]+=$(i+4) }} END {print sum[0] , sum[1]}'

输出:195 30

awk的基本使用就介绍到这里了,以后遇见啥新奇的用法再补充。

参考链接:
linux awk 命令

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值