Linux文本处理命令三剑客之——awk

awk原理

awk是把文件逐行读入,以空格为默认分隔符将每行切片,切开的部分叫做“域”,然周再对于每个域进行各种分析处理,如:去重、排序、执行计算、报表等等。

awk语法

awk 'pattern + {action}' {filename}

patternawk在数据中查找的内容
action :匹配内容时所执行的一系列命令
filename:要处理的文件

awk选项

  • -v:定义变量
  • -f:指定awk脚本
  • -F:指定分隔符,若有多个分隔符,使用 [.|>/]中括号,[]内可写正则表达式

awk调用方法

1、命令行

awk [-F 分隔符] 'commands' input-files

2、shell脚本

#!/bin/awk

3、awk编程文件

awk -f awk-script-file input-files

awk案例

1、显示linux下最后登陆的5个账号名

last -n 5 | awk '{print $1}'

工作流程:
从标准输出读入有\n 换行符分割的一条记录,然后将该记录按指定的域分隔符划分域,填充域。
$0:表示所有域
$1:第一个域
$2:第二个域
$NF:最后一个域
NR:已读记录数(当处理两个文件时,会从新计数)
FNR:已读记录数(当处理两个文件时,不会从新计数)
FILENAME:文件名

2、显示用户名和登陆shell,用tab分割,第一行显示name shell,最后一行显示end!

awk -F ":" 'BEGIN {print "name" "\t" "shell"} {print $1,$NF} END {print "end!"}' /etc/passwd

工作流程:
先执行BEGIN;然后读取文件,执行action;最后执行END

3、搜索有root关键字的所有行,输出对应的shell

awk -F ":" '/root/ {print $1,$NF}' /etc/passwd
awk -F: '/^.*root.*$ {print $1,$NF}' /etc/passwd

这种就是pattern的使用案例,匹配pattern (root)的行才会执行action。若没有指定action,默认输出每行的内容。
其中可使用printf代替print,可定义更加复杂的输出格式!

4、使用awk对一个文件的第3列进行去重

awk -F: '!a[$3]++ {print $3}' /etc/passwd

处理流程:

  • 在awk中,对于未初始化的数组变量,在进行数值运算时,会赋予初始值0,因此a[$3]=0
  • ++运算符的特征是先取值,后加1,因此pattern等价于!0
  • 0为假,!取反,因此pattern最后结果为1,就相当于if(1)pattern匹配成功,输出当前记录(执行的action
  • 最后a[$3]1
  • 当执行到下一回合,遇到重复的$3内容,此时a[$3]=1(因为上一步加1),取反为0,指为假,所以就不会输出了

5、统计当前文件夹下的文件大小总和,用MB展示

find ./ -type f | ls -l | awk 'BEGIN {size=0} {size += $5} END {print size / 1024 / 1024 "MB"}'

自定义变量size

6、统计当前文件夹下文件大小总和,排除4096大小的文件

ls -l | awk 'BEGIN {size=0} {if(size != 4096) {size += $5;}} END {print size / 2014 / 1024 "MB"}'

7、循环输出用户名

awk -F: 'BEGIN {count=0} {name[count]=$1; count++} END {for(i=0; i<NR; i++) print i, name[i]}' /etc/passwd

8、输出文件中第2列包含th的行,不区分大小写

awk 'BEGIN {IGNORECASE=1} $2~/th/' filename

IGNORECASE=1:忽略大小写
$2~/th/:第2列包含th

9、处理2个文件的情况。需要以a文件的第3列在b文件中进行过滤

awk -F "|" 'NR==FNR{a[$1]=$2}{if($1 ~ /^11\.[0-9]*\.[3,5]\.[0-9]*/) print $0,a[$3]}' b.txt a.txt

NR==FNR{a[$1]=$2}
a是一个数组;当NR==FNR,也就是读取第一个文件的内容(第一个文件就是后面的b.txt),以b.txt中的$1作为数组索引号,以b.txt中的$2作为数组的值;

if($1 ~ /^11\.[0-9]*\.[3,5]\.[0-9]*/) print $0,a[$3]
a.txt的第一列做正则匹配,同时输出$0,也就是所有列的内容。a[$3],数组是不变的,这里以a.txt文件的第3列为key,输出value如果key不存在时,则不做处理。这顺其自然就相当于过滤了b.txt的内容

awk gsub

awk内置函数gsub
gsub()gsub(r,s) 在整个$0中用s替代rgsub(r,s,t) 在整个t中用s替代r

此函数的另外的一个功能就是统计某个字符在一行中出现的次数

test cat a
sdhi bb
12 jj
bn 213hi
kjdhi bb hi hi
sjd 213hi

➜  test cat a | awk '{print NR,gsub("hi", "xx"),$0}'
1 1 sdxx bb
2 0 12 jj
3 1 bn 213xx
4 3 kjdxx bb xx xx
5 1 sjd 213xx

第一列:行号
第二列:hi字符被替换的次数
第三列:输出替换后的整行内容

awk总结

awk被誉为Linux下的文本处理三剑客之一,也是三剑客的第一个,它具有很强的文本处理能力,有些时候不一定要写很复杂的程序才能完成日志分析,其实用很简单的Linux命令就能完成需求,而且效率非常高。awk就是其中之一,剩下2个是sedgrep,下一篇文章我们再来分享sed命令!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值