awk 常用技巧

“ awk 一般用于比较规范的文件处理,是 sed 命令的补充。”

01—基本概念

awk 脚本的流程控制,主要包含三部分,第 1, 3 部分可忽略。

输入数据前 BEGIN{},数据处理前做一些预处理工作。主循环 {}。所有文件读取完成 END {}

每行称作 awk 的记录,默认使用空格、制表符分开,每个分开的单词叫做字段。

在 awk 中使用使用 $1 $2 ... $n 表示每一个字段($0 表示整行)。

可以用 -F 指定分隔符,分隔符也可以使用正则表达式。

awk -F ',' '{print $1,$2,$3}' filename

示例:

[/tmp]$ cat a.log
a,b,c,d,e
1,2,3,4
a,2,c
# 正则过滤,然后给每行一个编号,打印第二列
[/tmp]$ awk -F',' '/^[a-z]/{print x++,$2}' a.log
0 b
1 2

系统变量

  • FS:输入字段分隔符,等同于 -F
  • OFS:输出字段分隔符
  • RS:记录分隔符,默认是换行(\n)
  • NR 和 FNR 显示行号
  • NF 字段数量
# 更改输入和输出分隔符
[/tmp]$ awk 'BEGIN{FS=",";OFS="-"}{print $1,$2,$3}' a.log
a-b-c
1-2-3
a-2-c
# 更改记录分隔父
[/tmp]$ awk 'BEGIN{RS=","}{print $1,$2,$3}' a.log
a
b
c
d
e 1
2
3
4 a
2
c
# 显示行号 FNR 多个文件会重新计数
[/tmp]$ awk '{print NR,$0}' a.log
1 a,b,c,d,e
2 1,2,3,4
3 a,2,c
[/tmp]$ awk -F, '{print NF,$0}' a.log
5 a,b,c,d,e
4 1,2,3,4
3 a,2,c

02—条件和循环

这里的条件和循环跟编程语言的格式差不多。

条件

语法格式:

 if( expression ) statement [ else statement ]

示例:grades.log 中存放的第一列学生名,后面每列是成绩。

[/tmp]$ cat grades.log
user0 66 98 89 62 71
user1 63 93 70 93 85
user2 92 92 82 79 91
user3 91 77 83 63 74
user4 88 99 87 99 67
# if 内多个处理语句可以用 {} 括起来
[/tmp]$ awk '{if($2>80) print $1}' grades.log
user2
user3
user4

条件过滤

# 等同于上面 if
[/tmp]$ awk '$2>80 {print $1}' grades.log
user2
user3
user4
[/tmp]$ awk '$2>90 && $3>90' grades.log
user2 92 92 82 79 91
# // 中间是正则
[/tmp]$ awk '$1 ~ /[a-z]+1/ {print $0}' grades.log
user1 63 93 70 93 85

循环

while ( expr ) statement
do statement while ( expr )
for ( opt_expr ; opt_expr ; opt_expr ) statement
for ( var in array ) statement

示例:计算 grades.log 中每个学生的总成绩和平均成绩。

[/tmp]$ awk '{sum=0;for(i=2;i<=NF;i++) sum+=$i;print $1,sum,sum/(NF-1)}' grades.log
user0 386 77.2
user1 404 80.8
user2 436 87.2
user3 388 77.6
user4 440 88

03—数组

计算所有学生的平均值。

[/tmp]$ awk '{sum=0;for(i=2;i<=NF;i++) sum+=$i;arr[$1]=sum/(NF-1)}END{for(user in arr) sum1+=arr[user];print sum1/NR}' grades.log
82.16

命令行参数数组

这两个参数主要在写 shell 脚本比较常用,比如要给 awk 传入一些参数。

  • ARGC:参数数量
  • ARGV:存储参数的数组
[/tmp]$ cat arg.awk
BEGIN{
    for(i=0;i<ARGC;i++)
        print ARGV[i]
}
[/tmp]$ awk -f arg.awk a b c
awk
a
b
c

数组比较常用的是从 access 日志中统计请求的 ip,或者统计 url 的请求量。相比 sort + uniq -c 的统计方式,awk效率会高效很多。

04—文件拆分

比如我们要把平均成绩大于 80 分的同学单独保存到一个文件中。

[/tmp]$ awk '{sum=0;for(i=2;i<=NF;i++) sum+=$i;avg=sum/(NF-1);if(avg>80) print $1,avg > "80.log";}' grades.log
[/tmp]$ cat 80.log
user1 80.8
user2 87.2
user4 88

微信搜索 CoderMeng 关注获取更多干货文章。
在这里插入图片描述

大家觉得写的不错欢迎点赞评论分享支持。

推荐阅读
你所不知道的那些sed命令

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值