awk指令
awk指令
awk指令介绍:
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。
通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。
之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。
流程简介

如图所示,共分为读取文件前、读取文件、读取文件后三个阶段
基本介绍
- 语句的格式为:
awk 参数 '条件{动作}' 文件路径
,条件和动作标准的叫法是'pattern{action}'
,即模式和行为 - 若不加条件则对每一行都生效,若不加动作则默认显示这一行
- 默认以回车分隔每一行,以空格(或tab)分隔每一列
-F,
表示以,分隔每一列,如果分隔符不止一种,需要使用正则表达式- 命令行参数之后的内容用
''
- 字符串用
""
示例:
ls -l | awk '{print $5}'
:只有动作而无条件,意思是打印每一行的第五列

基本同上,输出每一行的第五列和第九列。顺带一提,
$NF
表示最后一列column -t
可以格式化输出结果

- 对以上规则的综合运用,添加BEGIN和END

行与列
行也称作记录,列也称作字段、域
取行
NR==1
:取出第一行NR>=1&&NR<=5
:取出1到5行/oldboy/
:传入正则表达式,得到匹配的行
取列
$数字
:取出某一列$0
:整行的内容$NF
:最后一列
实战:

-F"[ /]"
表示分隔符为空格或斜杠,对于第三行,第一个元素为空格,第二个元素为inet,第三个元素为10.0.0.61

内建变量
来自菜鸟教程,供参考:
变量 | 描述 |
---|---|
$n | 当前记录的第n个字段,字段间由FS分隔 |
$0 | 完整的输入记录 |
ARGC | 命令行参数的数目 |
ARGIND | 命令行中当前文件的位置(从0开始算) |
ARGV | 包含命令行参数的数组 |
CONVFMT | 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组 |
ERRNO | 最后一个系统错误的描述 |
FIELDWIDTHS | 字段宽度列表(用空格键分隔) |
FILENAME | 当前文件名 |
FNR | 各文件分别计数的行号 |
FS | 字段分隔符(默认是任何空格) |
IGNORECASE | 如果为真,则进行忽略大小写的匹配 |
NF | 一条记录的字段(列)的数目 |
NR | 已经读出的记录数,就是行号,从1开始 |
OFMT | 数字的输出格式(默认值是%.6g) |
OFS | 输出字段分隔符,默认值与输入字段分隔符一致。 |
ORS | 输出记录分隔符(默认值是一个换行符) |
RLENGTH | 由match函数所匹配的字符串的长度 |
RS | 记录分隔符(默认是一个换行符) |
RSTART | 由match函数所匹配的字符串的第一个位置 |
SUBSEP | 数组下标分隔符(默认值是/034) |
模式匹配
比较表达式
参考上方内容
正则
awk可以精确到某一列,通过某一列包含/不包含…内容来进行筛选,其中~
表示包含,!~
表示不包含
正则 | awk正则 |
---|---|
^ | 某一列的开头 $3~/^oldboy/ |
$ | 某一列的结尾 $4~/oldboy$/ |
^$ 空行 | 某一列是空的 |
实例:/etc/passwd文件中,以:分隔行,找出第三列以1或2开头的行,打印出该行的第一、三和最后一列

以下三种写法等价,推荐第一种:
1 | awk -F: '$3~/^[12]/{print $1,$3,$NF}' /etc/passwd |
表示范围
/开始/,/结束/
:较常用,要匹配文本的内容,见示例NR==1,NR==5
:从第一行到第五行结束
1 | 显示指定时间(11:02:00~11:02:30)范围内容的ip地址 |
由于每一条日志里都有时间的字段,awk就可以匹配这些时间,列出该时间范围内的日志
特殊模式
模式 | 含义 | 场景 |
---|---|---|
BEGIN{} | 里面的内容会在awk读取文件之前执行 | 进行简单统计、计算,不涉及读取文件 |
END{} | 里面的内容会在awk读取文件之后执行 | 1) awk进行统计,一般过程:先进行计算,最后在END里面输出结果 2) awk使用数组,用来输出数组结果 |
END统计方法(i和sum都是变量):
统计方法 | 简写形式 | 场景 |
---|---|---|
i=i+1 | i++ | 计数,统计次数 |
sum=sum+??? | sum+=??? | 求和,累加 |
示例:
- 统计空行的个数:
1 | 方法一:使用 wc -l 管道命令 |
- 求和:
1 | seq 100 | awk '{sum+=$1}END{print sum}' # 5050 |
补充:wc指令
Linux wc命令用于计算字数。
利用wc指令我们可以计算文件的Byte数、字数、或是列数,若不指定文件名称、或是所给予的文件名为”-“,则wc指令会从标准输入设备读取数据。
语法:wc [-clw][--help][--version][文件...]
参数:
- -c或–bytes或–chars 只显示Bytes数。
- -l或–lines 显示行数。
- -w或–words 只显示字数。
- –help 在线帮助。
- –version 显示版本信息。
在默认的情况下(不加选项),wc将计算指定文件的行数、字数,以及字节数
awk数组
用途:
- 统计次数:统计每个ip出现次数,统计每种状态码出现次数,统计系统中每个用户被攻击的次数,统计攻击者ip出现次数
- 累加求和:统计每个ip消耗的流量
shell数组 | awk数组 | |
---|---|---|
形式 | array[0]=oldboy | array[0]=oldboy |
使用 | echo ${array[0]} | print array[0] |
批量输出数组内容 | for i in ${array[*]} do echo ${array[i]} done |
for(i in array) print array[i] |
示例:
1 | awk 'BEGIN{a[0]=12345;a[1]="danmo"; for(i in a) print a[i]}' |
演示统计功能:
假设这是一个log内的信息:

awk数组可以进行分类统计,在此例中,则是统计每个顶级域名出现的次数

补充:sort指令
Linux sort 命令用于将文本文件内容加以排序。
sort 可针对文本文件的内容,以行为单位来排序。
语法:
1 | sort [-bcdfimMnr][-o<输出文件>][-t<分隔字符>][+<起始栏位>-<结束栏位>][文件][-k field1[,field2]] |
- -b 忽略每行前面开始出的空格字符。
- -c 检查文件是否已经按照顺序排序。
- -d 排序时,处理英文字母、数字及空格字符外,忽略其他的字符。
- -f 排序时,将小写字母视为大写字母。
- -i 排序时,除了040至176之间的ASCII字符外,忽略其他的字符。
- -m 将几个排序好的文件进行合并。
- -M 将前面3个字母依照月份的缩写进行排序。
- -n 依照数值的大小排序。
- -u 意味着是唯一的(unique),输出的结果是去完重了的。
- -o<输出文件> 将排序后的结果存入指定的文件。
- -r 以相反的顺序来排序。
- -t<分隔字符> 指定排序时所用的栏位分隔字符。
- +<起始栏位>-<结束栏位> 以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。
- [-k field1[,field2]] 按指定的列进行排序。
sort排序是不改变源文件的,可以-o <输出文件>
来将修改后的内容存入一个新的文件
流程控制
for
示例:
1 | awk 'BEGIN{for(i=1;i<=100;i++){sum+=1} print sum}' |
if
示例:

查找占用容量超过1%的行,显示其第1、5和最后一列

面试题:输出长度小于6的列(字段):
