废话不多说,man一下
name : pattern scanning and text processing language
模式扫描和文本处理语言
简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk擅长列输出
awk ‘{pattern + action}’ {filenames}
pattern 表示 AWK 在数据中查找的内容
action 是在找到匹配内容时所执行的一系列命令
awk内置变量
变量 | 含义 |
---|---|
ARGC | 命令行参数个数 |
ARGV | 命令行参数排列 |
ENVIRON | 支持队列中系统环境变量的使用 |
FILENAME | awk浏览的文件名 |
FNR | 浏览文件的记录数 |
FS | 设置输入域分隔符,等价于命令行 -F选项 |
NF | 浏览记录的域的个数 |
NR | 已读的记录数 |
OFS | 输出域分隔符 |
ORS | 输出记录分隔符 |
RS | 控制记录分隔符 |
$0 | 是指整条记录 |
$1 | 当前行的第一个域,$2表示当前行的第二个域,…以此类推。 |
$NF | number finally,表示最后一列的信息,跟变量NF是有区别的,变量NF统计的是每行列的总数 |
一般都会拿/etc/passwd举列子,那我们也用这个吧
首先cat
root@ubuntu:/# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
根据之前提到的语法 awk ‘{pattern + action}’ {filenames}
pattern 为 ‘/root/’
filenames 为 /etc/passwd
action 如果没写 默认输出每行的内容
搜索/etc/passwd有root关键字的所有行
root@ubuntu:/# awk '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
因为是默认输出每行内容,那么也可以这么使用,因为$0是输出整行
awk '/root/ {print $0}' /etc/passwd
如果想获得 /etc/passwd有root关键字的所有行,并显示对应的shell
我们尝试 awk -F: ‘/root/ {print $7}’ /etc/passwd
root@ubuntu:/# awk '/root/ {print $7}' /etc/passwd
root@ubuntu:/#
竟然什么也输出不来,理论上是输出 /bin/bash 的
我们查看awk的内置变量 FS变量 设置输入域分隔符,等价于命令行 -F选项
分割符是:那么就是 -F :
然后命令为 awk -F: ‘/root/ {print $7}’ /etc/passwd
root@ubuntu:/# awk -F: '/root/ {print $7}' /etc/passwd
/bin/bash
root@ubuntu:/#
统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:
root@ubuntu:/# 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
filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
使用这个也可以awk -F: ‘{printf (“filename:%10s, linenumber:%3s,column:%3s,content:%3f\n”,FILENAME,NR,NF,$0)}’ /etc/passwd
root@ubuntu:/# awk -F: '{printf ("filename:%10s, linenumber:%3s,column:%3s,content:%3f\n",FILENAME,NR,NF,$0)}' /etc/passwd
filename:/etc/passwd, linenumber: 1,column: 7,content:0.000000
filename:/etc/passwd, linenumber: 2,column: 7,content:0.000000
awk -F “:” ‘{print $NF}’ /etc/passwd 代表查询最后一列 以":“为分隔符
awk -F “/” ‘{print $NF}’ /etc/passwd 代表查询最后一列 以”/"为分隔符
root@ubuntu:/# awk -F "/" '{print $NF}' /etc/passwd
bash
nologin
nologin
获取第12到31行的第一列的信息
awk -F “:” ‘{if(NR<31 && NR >12) print $1}’ /etc/passwd
root@ubuntu:/# cat /etc/passwd | awk -F: 'BEGIN{print "name, shell"} {print $1,$NF} END{print "hello world"}'
name, shell
root /bin/bash
daemon /usr/sbin/nologin
bin /usr/sbin/nologin
sys /usr/sbin/nologin
sync /bin/sync
games /usr/sbin/nologin
man /usr/sbin/nologin
lp /usr/sbin/nologin
mail /usr/sbin/nologin
news /usr/sbin/nologin
uucp /usr/sbin/nologin
proxy /usr/sbin/nologin
www-data /usr/sbin/nologin
backup /usr/sbin/nologin
list /usr/sbin/nologin
irc /usr/sbin/nologin
gnats /usr/sbin/nologin
nobody /usr/sbin/nologin
systemd-timesync /bin/false
systemd-network /bin/false
systemd-resolve /bin/false
systemd-bus-proxy /bin/false
syslog /bin/false
_apt /bin/false
messagebus /bin/false
uuidd /bin/false
lightdm /bin/false
whoopsie /bin/false
avahi-autoipd /bin/false
avahi /bin/false
dnsmasq /bin/false
colord /bin/false
speech-dispatcher /bin/false
hplip /bin/false
kernoops /bin/false
pulse /bin/false
rtkit /bin/false
saned /bin/false
usbmux /bin/false
wmz /bin/bash
ftp /bin/false
tftp /bin/false
statd /bin/false
sshd /usr/sbin/nologin
hello world
root@ubuntu:/#
除了awk的内置变量,awk还可以自定义变量, awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同
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后只显示最后的结果】
root@ubuntu:/# ls -l|awk '{if($5>100){count++; sum+=$5}} {print "Count:" count,"Sum: " sum}'
Count: Sum:
Count:1 Sum: 4096
Count:2 Sum: 8192
Count:3 Sum: 12288
Count:4 Sum: 16288
Count:5 Sum: 28576
Count:6 Sum: 32672
Count:6 Sum: 32672
Count:6 Sum: 32672
Count:7 Sum: 36768
Count:8 Sum: 40864
Count:9 Sum: 44960
Count:10 Sum: 61344
Count:11 Sum: 65440
Count:12 Sum: 69536
Count:13 Sum: 73632
Count:13 Sum: 73632
Count:14 Sum: 77728
Count:15 Sum: 78728
Count:16 Sum: 91016
Count:17 Sum: 95112
Count:18 Sum: 99208
Count:18 Sum: 99208
Count:19 Sum: 103304
Count:20 Sum: 107400
Count:21 Sum: 111496
Count:21 Sum: 111496
Count:21 Sum: 111496
root@ubuntu:/# ls -l|awk '{if($5>100){count++; sum+=$5}} END{print "Count:" count,"Sum: " sum}'
Count:21 Sum: 111496