很久之前学的AWK,现在回看笔记,对其进行一个小小的总结~
目录
awk可以做什么?
1. 能够将给定的文本内容,按照我们期望的格式输出显示,打印成报表。
2. 分析处理系统日志,快速地分析挖掘我们关心的数据,并生成统计信息;
3. 方便地用来统计数据,比如网站的访问量,访问的 IP 量等;
4. 通过各种工具的组合,快速地汇总分析系统的运行信息,让你对系统的运行了如指掌;
5. 强大的脚本语言表达能力,支持循环、条件、数组等语法,助你分析更加复杂的数据;
awk 比较擅长处理格式化的文本,比如 日志、csv 格式数据
awk 基本命令格式
awk 'BEGIN{ action;.... }pattern{ action;... }END{ action;.... }' file
常见的Action分类:
表达式:算术,比较表达式
条件控制语句:if,while等
组合语句
输出语句:print等

分隔符、域和记录
awk执行时,有分隔符分隔的字段(域)标记 $1,$2,...$n成为域标识。$0表示所有域(F)。可以通过-F=‘’ 来指定分隔符,如-F=':' 或者-F:表示分隔符为冒号
文件的每一行为记录(R) ,
当省略action,默认执行print $0
awk内置变量
引用时无需$
FS:输入字段分隔符,默认是空白字符
awk -v FS=':' '{print $1,FS,$3}' /etc/passwd
awk -F='2019' '{print $1,"*",$2}' file.txt
以:为分隔符,过滤出第一列和第三列,输出时两列间以:为分隔符
以2019为分隔符,用*替换2019
OFS:指定输出时的分隔符
RS:输入记录分隔符,指定输入是的换行符
NF:当前的列数
awk '{print $1,$2,$3,$4}' OFS=":" file.txt
输出时,字段间用OFS指定输出分隔符为:
NR:当前的行数
输出格式printf命令
printf需要给出换行控制符,\n
%d显示十进制整数,%f显示浮点数,%s显示字符串,%%显示%自身
-
%u
十进制无符号整数 -
%c
单个字符 -
%e
指数形式的浮点数 -
%x
%X
无符号以十六进制表示的整数 -
%0
无符号以八进制表示的整数 -
%g
自动选择合适的表示法 -
\n
换行符 -
\t
Tab符
修饰符:
-:左对齐(默认右对齐)
+:显示数值的正负符号%+d
%3.1f :第一个数字控制显示的宽度,第二个表示小数点后的精度
awk '{printf "%-4s %-6s\n",$1,$2}' file.txt
左对齐,列宽为4,%s为字符串占位符。
awk 支持各种比较运算符号
==,!=,>,>=,<.<=
还支持逻辑操作符来过滤
&&与 ||或 !非
awk -F: '$3==0 || $6>=1000 {print $0}' /etc/passwd
以上过滤条件为第三列等于0或者第六列大于等于1000的行才被输出
模式匹配符 ~
awk -F: '$0 ~ /root/ {print $1}' /etc/passwd
匹配含有root,输出第一列
同样,awk也支持象grep一样匹配某一行
awk '/OS Name|OS Version/' file.txt
匹配多个关键词
模式取反!
awk '!/Aug/' file.txt
awk基础应用:
(一)统计字符串次数
统计file.txt中每个字符串出现的次数
welcome nowcoder
welcome to nowcoder
nowcoder
awk '{for(i=1;i<=NF;i++)arr[$i]++}END{for(pattern in arr)print pattern,arr[pattern]}' nowcoder.txt
>>
to 1
welcome 2
nowcoder 3
统计每个用户的进程占用了多少内存,需要注意的是,取值的是RSS那一列。
ps aux | awk 'NR!=1 {a[$1]+=$6} END{for(i in a) print i,a[i]}'
>>
geoclue 16976
rpc 1384
colord 6156
rtkit 1796
rpcuser 1820
polkitd 12324
dbus 4228
nobody 1100
libstor+ 824
avahi 2468
mysql 84804
root 1310236
[root@node01 ~]#ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 1.5 0.2 191272 4216 ? Ss 20:13 0:02 /usr/lib/syste
root 2 0.0 0.0 0 0 ? S 20:13 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 20:13 0:00 [kworker/0:
统计当前目录下,*.txt的文件所占空间大小之和
ls -l *.txt | awk '{sum+=$5} END{print sum}'
[root@node01 ~]#ls -l
total 14980
-rw-r--r--. 1 root root 518505 Nov 16 2021 all.sql
-rw-r--r-- 1 root root 8 May 6 16:12 a.log
第五列为文件大小
(二)文件拆分
awk支持重定向符号>,直接将第五列内容相同的行写至一个新文件,且文件名为第五列
awk '{print $0 > $5} file.txt'
root@node01 ~]#cat file.txt
rwxr-xr-x. 2 root root 6 Jun 20 2021 Pictures
drwxr-xr-x. 2 root root 6 Jun 20 2021 Public
-rw-r--r-- 1 root root 78 Dec 28 08:43 python.sh
-rwxr-xr-x 2 root root 5259480 Dec 4 02:42 qemu-kvm
-rw-r--r--. 1 root root 38 Jul 13 2021 sed.txt
drwxr-xr-x. 3 root root 25 Jul 16 2021 src
root@node01 ~]#cat Jun
rwxr-xr-x. 2 root root 6 Jun 20 2021 Pictures
drwxr-xr-x. 2 root root 6 Jun 20 2021 Public
(三)处理文本
111:13443
222:13211
111:13643
333:12341
222:12123
按照以下格式输出
[111]
13443
13643
[222]
13211
12123
[333]
12341
awk -v FS=":" '{a[$1] = a[$1] $2 "\n"} END {for (i in a){printf("[%s]\n%s",i,a[i])}}' file.txt
(四)字符串操作
awk 支持对字符串de操作
awk '{if(length($4) == 4) print $2,toupper($3)}' file.txt
length计算字符串长度,toupper函数转换字符串为大写。
比较常用的字符串函数:
-
index(s, t)
返回子串 t 在 s 中的位置 -
length(s)
返回字符串 s 的长度 -
split(s, a, sep)
分割字符串,并将分割后的各字段存放在数组 a 中 -
substr(s, p, n)
根据参数,返回子串 -
tolower(s)
将字符串转换为小写 -
toupper(s)
将字符串转换为大写 -
substr(str,pos,len)从pos开始的位置,截取len个字符;
-
substr(str,pos) pos开始的位置,一直截取到最后。