awk原理
awk是把文件逐行读入,以空格为默认分隔符将每行切片,切开的部分叫做“域”,然周再对于每个域进行各种分析处理,如:去重、排序、执行计算、报表等等。
awk语法
awk 'pattern + {action}' {filename}
pattern:awk在数据中查找的内容
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等价于!00为假,!取反,因此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替代r;gsub(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个是sed和grep,下一篇文章我们再来分享sed命令!
本文深入讲解awk命令的原理与应用,包括awk的基本语法、选项、调用方法及多个实用案例,如去重、统计文件大小、输出特定字段等,帮助读者掌握awk在Linux文本处理中的强大功能。
1632

被折叠的 条评论
为什么被折叠?



