简介
发现一个强大的命令,awk。在日常查看日志中使用awk分组统计犹如神助攻。
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。
使用方法
awk '{pattern + action}' {filename}
尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。
awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。
通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。
入门实例
显示磁盘使用情况
yinbingyu@yby ~> df -h | awk '{print $1}'
Filesystem
/dev/disk1
devfs
map
map
awk工作流程是这样的:读入有’\n’换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$3
则表示所有域,$1
表示第一个域,$n
表示第n个域。默认域分隔符是”空白键” 或 “tab键”,所以$1
表示登录用户,$3表示登录用户ip,以此类推。如果没有标明是哪个域,默认是打印整行。
两个命令显示的内容是一致的。
指定域分隔符
yinbingyu@yby ~> df -h | awk -F '/' '{print $2}'
dev
dev
net
home
这种是awk+action的示例,每行都会执行action{print $1}。
-F指定域分隔符为’/’,其中指定域分隔符必须使用单引号。
如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割
yinbingyu@yby ~> awk -F ':' '{print $1 "\t" $7}' /etc/passwd
nobody /usr/bin/false
root /bin/sh
daemon /usr/bin/false
_uucp /usr/sbin/uucico
_taskgated /usr/bin/false
如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在所有行添加列名name,shell,在最后一行添加”blue,/bin/nosh”。
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'
name,shell
root,/bin/bash
daemon,/bin/sh
bin,/bin/sh
sys,/bin/sh
....
blue,/bin/nosh
awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0
则表示所有域,$1
表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。
条件搜索/正则
搜索有root关键字的所有行
yinbingyu@yby ~> awk -F: '/root/' /etc/passwd
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
_cvmsroot:*:212:212:CVMS Root:/var/empty:/usr/bin/false
或者输出指定的域
yinbingyu@yby ~> awk -F: '/root/{print $1}' /etc/passwd
root
daemon
_cvmsroot
正则搜索,以root开头的
yinbingyu@yby ~> awk -F: '/^root/{print $7}' /etc/passwd
/bin/sh
循环/统计
grep '系统异常' error.log | awk -F ':' '{print $2}' | awk '{arr[$1]+=1}END{for(i in arr)print i,arr[i]}'|sort -t ' ' -n -k2