参考文献:https://www.cnblogs.com/jiqianqian/p/7944013.html
awk是一个强大的文本分析工具。相较于sed常常一整行处理,awk则比较倾向于一行当中分成数个“字段”处理,简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
语法:
awk ‘条件类型1{动作1} 条件类型2{动作2} ...‘ filename
awk [options] ‘pattern{action}‘ file
1.查看最近5条登录用户和ip地址
awk工作流程是这样的:读入有’\n’换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,0则表示所有域,01表示第一个域,n表示第n个域。默认域分隔符是"空白键"或"[tab]键",所以1表示登录用户,$3表示登录用户ip,以此类推。
$ last -n 5|awk ‘{print $1"\t"$3}‘ lzyer 192.168.56.1 reboot boot
wtmp Sat
$ last -n 5|awk ‘{print $1,$3}‘ lzyer 192.168.56.1 reboot boot
wtmp Sat
只处理第一行的数据
$ last -n 5|awk ‘NR==1{print $1,$3}‘ lzyer 192.168.56.1
2.print和printf
awk中同时提供了print和printf两种打印输出的函数。
其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。
printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。
1. 使用printf输出的文本不会换行,如果需要换行,可以在对应的“格式替换符”后加入“\n”进行转义
2. 使用printf输出时,“指定的格式”与“被格式化的文本”之间,要用“,”隔开
3. 使用printf输出时,“格式”中的“格式替换符”必须与“被格式化的文本”一一对应(个数要相同)
eg:
1.#awk -F ‘:‘ ‘{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}‘ /etc/passwd filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash 2.awk -F ‘:‘ ‘{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}‘ /etc/passwd
3.正则匹配
搜索/etc/passwd有root关键字的所有行
awk -F: ‘/root/‘ /etc/passwd root:x:0:0:root:/root:/bin/bash
这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)。
搜索支持正则,例如找root开头的: awk -F: ‘/^root/’ /etc/passwd
搜索/etc/passwd有root关键字的所有行,并显示对应的shell
awk -F: ‘/root/{print $7}‘ /etc/passwd /bin/bash
这里指定了action{print $7}
4.awk内置变量
awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
5.常用参数
1. -F awk -F: ‘NR==1{print}‘ /etc/passwd root:x:0:0:root:/root:/bin/bash 2. -v var1=100 echo |awk -v var=$var1 ‘{print var}‘ 100
awk -v FS=":" ‘NR==1{print}‘ /etc/passwd root:x:0:0:root:/root:/bin/bash awk -v FS=":" -v OFS="#" ‘NR==1{print $1,$2}‘ /etc/passwd root#x
6. 关系运算符
关系运算符 | 含义 | 用法实例 |
< | 小于 | x<y |
<= | 小于等于 | x<=y |
> | 大于 | x>y |
>= | 大于等于 | x>=y |
== | 等于 | x==y |
!= | 不等于 | x!=y |
~ | 匹配 | x~/正则表达式/ |
!~ | 不匹配 | x!~/正则表达式/ |
7.其他栗子
举例来说,在 /etc/passwd 当中是以冒号 ":" 来作为字段的分隔, 该文件中第一字段为帐号,第三字段则是 UID。那假设我要查阅,第三栏小于 10 以下的数据,并且仅列出帐号与第三栏, 那么可以这样做:
$ cat /etc/passwd|awk ‘{FS=":"} $3<10 {print $0}‘ root:x:0:0:root:/root:/bin/zsh bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
统计数据例子:
$ cat pay.txt Name 1st 2nd 3th VBird 23000 24000 25000 DMTsai 21000 20000 23000 Bird2 43000 42000 41000
$ cat pay.txt|awk ‘NR==1{printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"} NR>=2{total=$2+$3+$4 > printf "%10s %10d %10d %10d %10.2f\n",$1,$2,$3,$4,total}‘ Name 1st 2nd 3th Total VBird 23000 24000 25000 72000.00 DMTsai 21000 20000 23000 64000.00 Bird2 43000 42000 41000 126000.00