awk命令详解

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

使用方法   : awk '{pattern + action}' {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

awk程序的报告生成能力通经常使用来从大文本文件里提取数据元素并将它们格式化成可读的报告。最完美的样例是格式化日志文件。

 

awk的用法

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

 第一步:运行BEGIN{ commands }语句块中的语句。

 第二步:从文件或标准输入(stdin)读取一行。然后运行pattern{ commands }语句块,它逐行扫描文件,从第一行到最后一行反复这个过程。直到文件所有被读取完成。

 第三步:当读至输入流末尾时。运行END{ commands }语句块。

 BEGIN语句块在awk開始从输入流中读取行之前被运行,这是一个可选的语句块,比方变量初始化、打印输出表格的表头等语句通常能够写在BEGIN语句块中。

 END语句块在awk从输入流中读取全然部的行之后即被运行。比方打印全部行的分析结果这类信息汇总都是在END语句块中完毕,它也是一个可选语句块。

 pattern语句块中的通用命令是最重要的部分,它也是可选的。假设没有提供pattern语句块,则默认运行{ print },即打印每个读取到的行。awk读取的每一行都会运行该语句块。 

 这三个部分缺少任何一部分都可以。

 

内建变量

$0        当前记录(这个变量中存放着整个行的内容)
$1~$n     当前记录的第n个字段,字段间由FS分隔
FS        输入字段分隔符 默认是空格或Tab
NF        当前记录中的字段个数,就是有多少列
NR        已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
FNR       当前记录数,与NR不同的是,这个值会是各个文件自己的行号
RS        输入的记录分隔符, 默认为换行符
OFS       输出字段分隔符, 默认也是空格
ORS       输出的记录分隔符,默认为换行符
FILENAME  当前输入文件的名字
ll /var/spool/

drwxr-xr-x.  2 root root  63 8月   6 14:19 anacron
drwx------.  2 root root   6 4月  11 2018 cron
drwxr-xr-x.  2 root root   6 4月  11 2018 lpd
drwxrwxr-x.  2 root mail 100 8月  10 16:53 mail
drwxr-xr-x.  2 root root   6 4月  13 2018 plymouth
drwxr-xr-x. 16 root root 201 8月   6 14:19 postfix

  ls -lh | awk '{print $1}'

  drwxr-xr-x.
  drwx------.
  drwxr-xr-x.
  drwxrwxr-x.
  drwxr-xr-x.
  drwxr-xr-x.

 

打印每一行的行数:

ls -lh | awk '{print NR " " $1}'

1 总用量
2 drwxr-xr-x.
3 drwx------.
4 drwxr-xr-x.
5 drwxrwxr-x.
6 drwxr-xr-x.
7 drwxr-xr-x.
awk  -F ':'  '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd

filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash filename:/etc/passwd,linenumber:2,columns:7,linecontent:bin:x:1:1:bin:/bin:/sbin/nologin filename:/etc/passwd,linenumber:3,columns:7,linecontent:daemon:x:2:2:daemon:/sbin:/sbin/nologin filename:/etc/passwd,linenumber:4,columns:7,linecontent:adm:x:3:4:adm:/var/adm:/sbin/nologin filename:/etc/passwd,linenumber:5,columns:7,linecontent:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin filename:/etc/passwd,linenumber:6,columns:7,linecontent:sync:x:5:0:sync:/sbin:/bin/sync filename:/etc/passwd,linenumber:7,columns:7,linecontent:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown filename:/etc/passwd,linenumber:8,columns:7,linecontent:halt:x:7:0:halt:/sbin:/sbin/halt filename:/etc/passwd,linenumber:9,columns:7,linecontent:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin filename:/etc/passwd,linenumber:10,columns:7,linecontent:operator:x:11:0:operator:/root:/sbin/nologin filename:/etc/passwd,linenumber:11,columns:7,linecontent:games:x:12:100:games:/usr/games:/sbin/nologin filename:/etc/passwd,linenumber:12,columns:7,linecontent:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin filename:/etc/passwd,linenumber:13,columns:7,linecontent:nobody:x:99:99:Nobody:/:/sbin/nologin filename:/etc/passwd,linenumber:14,columns:7,linecontent:systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin filename:/etc/passwd,linenumber:15,columns:7,linecontent:dbus:x:81:81:System message bus:/:/sbin/nologin filename:/etc/passwd,linenumber:16,columns:7,linecontent:polkitd:x:999:998:User for polkitd:/:/sbin/nologin filename:/etc/passwd,linenumber:17,columns:7,linecontent:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin filename:/etc/passwd,linenumber:18,columns:7,linecontent:postfix:x:89:89::/var/spool/postfix:/sbin/nologin filename:/etc/passwd,linenumber:19,columns:7,linecontent:mrzhao:x:1000:1000:mrzhao:/home/mrzhao:/bin/bash filename:/etc/passwd,linenumber:20,columns:7,linecontent:ntp:x:38:38::/etc/ntp:/sbin/nologin filename:/etc/passwd,linenumber:21,columns:7,linecontent:apache:x:1001:1001::/home/apache:/sbin/nologin filename:/etc/passwd,linenumber:22,columns:7,linecontent:mysql:x:1002:1002::/home/mysql:/sbin/nologin filename:/etc/passwd,linenumber:23,columns:7,linecontent:saslauth:x:998:76:Saslauthd user:/run/saslauthd:/sbin/nologin filename:/etc/passwd,linenumber:24,columns:7,linecontent:redis:x:1003:1003::/home/redis:/sbin/nologin filename:/etc/passwd,linenumber:25,columns:7,linecontent:memcached:x:1004:1004::/home/memcached:/sbin/nologin filename:/etc/passwd,linenumber:26,columns:7,linecontent:git:x:1005:1005::/home/git:/bin/bash

使用printf替代print,可以让代码更加简洁,易读

awk -F: '{printf ("filename:%10s, linenumber:%3s,column:%3s,content:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd

filename:/etc/passwd, linenumber:  1,column:  7,content:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd, linenumber:  2,column:  7,content:bin:x:1:1:bin:/bin:/sbin/nologin
filename:/etc/passwd, linenumber:  3,column:  7,content:daemon:x:2:2:daemon:/sbin:/sbin/nologin
filename:/etc/passwd, linenumber:  4,column:  7,content:adm:x:3:4:adm:/var/adm:/sbin/nologin
filename:/etc/passwd, linenumber:  5,column:  7,content:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
filename:/etc/passwd, linenumber:  6,column:  7,content:sync:x:5:0:sync:/sbin:/bin/sync
filename:/etc/passwd, linenumber:  7,column:  7,content:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
filename:/etc/passwd, linenumber:  8,column:  7,content:halt:x:7:0:halt:/sbin:/sbin/halt
filename:/etc/passwd, linenumber:  9,column:  7,content:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
filename:/etc/passwd, linenumber: 10,column:  7,content:operator:x:11:0:operator:/root:/sbin/nologin
filename:/etc/passwd, linenumber: 11,column:  7,content:games:x:12:100:games:/usr/games:/sbin/nologin
filename:/etc/passwd, linenumber: 12,column:  7,content:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
filename:/etc/passwd, linenumber: 13,column:  7,content:nobody:x:99:99:Nobody:/:/sbin/nologin
filename:/etc/passwd, linenumber: 14,column:  7,content:systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
filename:/etc/passwd, linenumber: 15,column:  7,content:dbus:x:81:81:System message bus:/:/sbin/nologin
filename:/etc/passwd, linenumber: 16,column:  7,content:polkitd:x:999:998:User for polkitd:/:/sbin/nologin
filename:/etc/passwd, linenumber: 17,column:  7,content:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
filename:/etc/passwd, linenumber: 18,column:  7,content:postfix:x:89:89::/var/spool/postfix:/sbin/nologin
filename:/etc/passwd, linenumber: 19,column:  7,content:mrzhao:x:1000:1000:mrzhao:/home/mrzhao:/bin/bash
filename:/etc/passwd, linenumber: 20,column:  7,content:ntp:x:38:38::/etc/ntp:/sbin/nologin
filename:/etc/passwd, linenumber: 21,column:  7,content:apache:x:1001:1001::/home/apache:/sbin/nologin
filename:/etc/passwd, linenumber: 22,column:  7,content:mysql:x:1002:1002::/home/mysql:/sbin/nologin
filename:/etc/passwd, linenumber: 23,column:  7,content:saslauth:x:998:76:Saslauthd user:/run/saslauthd:/sbin/nologin
filename:/etc/passwd, linenumber: 24,column:  7,content:redis:x:1003:1003::/home/redis:/sbin/nologin
filename:/etc/passwd, linenumber: 25,column:  7,content:memcached:x:1004:1004::/home/memcached:/sbin/nologin
filename:/etc/passwd, linenumber: 26,column:  7,content:git:x:1005:1005::/home/git:/bin/bash

 

搜索/etc/passwd有root关键字的所有行

awk  '/root/' /etc/passwd

root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin

 

搜索/etc/passwd有root关键字的所有行,并显示对应的shell

awk -F: '/root/ {print $7}' /etc/passwd

/bin/bash
/sbin/nologin

 

打印/etc/passwd/的第二行信息

awk -F: 'NR==2{print "filename: "FILENAME, $0}' /etc/passwd

filename: /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologin

 

awk的过滤使用方法

列出目录下所有得文件夹

ls -lF | awk '/^d/'

drwxr-xr-x.  2 root root  63 8月   6 14:19 anacron/
drwx------.  2 root root   6 4月  11 2018 cron/
drwxr-xr-x.  2 root root   6 4月  11 2018 lpd/
drwxrwxr-x.  2 root mail 100 8月  10 16:53 mail/
drwxr-xr-x.  2 root root   6 4月  13 2018 plymouth/
drwxr-xr-x. 16 root root 201 8月   6 14:19 postfix/

 

指定特定的分隔符,查询第一列

awk -F ":" '{print $1}' /etc/passwd

root bin daemon adm lp sync shutdown halt mail operator games ftp nobody systemd-network dbus polkitd sshd postfix mrzhao ntp apache mysql saslauth redis memcached git

 

指定特定的分隔符,查询最后一列

 

awk -F ":" '{print $NF}' /etc/passwd

/bin/bash /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /bin/sync /sbin/shutdown /sbin/halt /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /bin/bash /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /bin/bash

 

获取第12到31行的第一列的信息
awk -F ":"  '{if(NR<31 && NR >12) print $1}' /etc/passwd

nobody
systemd-network
dbus
polkitd
sshd
postfix
mrzhao
ntp
apache
mysql
saslauth
redis
memcached
git

 

多分隔符的使用:

awk -F "[/]" 'NR == 4 {print $0,"\n",$1}' /etc/passwd

adm:x:3:4:adm:/var/adm:/sbin/nologin adm:x:3:4:adm:

 

添加了BEGIN和END

cat /etc/passwd | awk -F: 'BEGIN{print "name, shell"} {print $1,$NF} END{print "hello  world"}'

name, shell
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
systemd-network /sbin/nologin
dbus /sbin/nologin
polkitd /sbin/nologin
sshd /sbin/nologin
postfix /sbin/nologin
mrzhao /bin/bash
ntp /sbin/nologin
apache /sbin/nologin
mysql /sbin/nologin
saslauth /sbin/nologin
redis /sbin/nologin
memcached /sbin/nologin
git /bin/bash
hello  world

 

查看最近登录最多的IP信息

last | awk '{S[$3]++} END{for(a in S ) {print S[a],a}}' |uniq| sort -rh

5 mrzhaodembp.lan
4 Tue
3 boot
1 Fri
1

 

awk编程--变量和赋值

除了awk的内置变量,awk还可以自定义变量, awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同。

统计某个文件夹下的大于100k文件的数量和总和

ls -l|awk '{if($5>100){count++; sum+=$5}} {print "Count:" count,"Sum: " sum}'    【因为awk会轮询统计,所以会显示整个过程】
ls -l|awk '{if($5>100){count++; sum+=$5}} END{print "Count:" count,"Sum: " sum}' 【天界END后只显示最后的结果】

count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开

  

 

统计显示/etc/passwd的账户

awk -F: '{count++;} END{print count}' /etc/passwd        
cat /etc/passwd|wc -l
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
#上面三个命令显示一致

 

 
 

 

 

 

 

posted @ 2019-08-22 13:50  龙福  阅读(834)  评论(0编辑  收藏  举报