linux学习笔记--awk命令详解

linux学习笔记--awk命令详解

作用:数据处理工具,用于把一行中分成数个字段处理(切割)

  • 语法规则: awk '条件类型 1 {操作1} 条件类型2 {操作2} ...' filename

awk主要处理一行内的数据,默认的分隔符为“空格键”或“TAB键”

  • 例:找出登录这着的账号与ip
[root@localhost ~]# last -n 5
root     pts/1        192.168.43.99    Thu Mar 12 10:25   still logged in   
root     tty1                          Thu Mar 12 10:24   still logged in   
root     pts/0        192.168.43.99    Thu Mar 12 09:55 - 10:26  (00:31)    
reboot   system boot  3.10.0-1062.12.1 Thu Mar 12 09:55 - 11:12  (01:17)    
root     pts/0        192.168.43.99    Wed Mar 11 17:06 - down   (00:09)    

wtmp begins Sat Nov 16 04:06:53 2019
[root@localhost ~]# last -n 5 | awk '{print $1 "	" $3}'
root	192.168.43.99
root	Thu
root	192.168.43.99
reboot	boot
root	192.168.43.99
	
wtmp	Sat

几个变量的说明($0 $1 $2 ...)

上面例子中$1是root,是该行第一栏的内容,$3是192.168.43.99 ,是该行第三栏的内容。$0代表一整行数据。

awk处理流程

  1. 读入第一行,将第一行数据写入$0 $1 $2...中
  2. 根据“条件类型”的限制判断是否进行后面“操作”(上例中因为每行都要操作,因此没有设置条件类型)
  3. 若为多行,则在重复执行1,2

awk内置变量

变量名称 含义
NF 每行($0)拥有的字段数
NR 目前awk所处理第几行
FS 目前分割字符,默认为空格键
FILENAME awk浏览的文件名
... ...
  • 例:在上例中列出每行行号($1);列出目前处理行数;列出该行字段数
[root@localhost ~]# last -n 5 | awk '{print $1 "	 lines: " NR "	 columns:" NF}'
root	 lines: 1	 columns:10
root	 lines: 2	 columns:9
root	 lines: 3	 columns:10
reboot	 lines: 4	 columns:11
root	 lines: 5	 columns:10
	 lines: 6	 columns:0
wtmp	 lines: 7	 columns:7

awk逻辑运算符

运算单元 含义
> 大于
< 小于
>= 大于等于
<= 小于等于
== 等于
!= 不等于

实验练习

  • 例:列出/etc/passwd中第一个字段用户,第三个字段UID,并设置仅查看第三栏小于10的数据
[root@localhost ~]# cat /etc/passwd | awk '{FS=":"} $3<10 {print $1 "	" $3}'
root:x:0:0:root:/root:/bin/bash	
bin	1
daemon	2
adm	3
lp	4
sync	5
shutdown	6
halt	7
mail	8

这有一个为问题:第一行没有正确分割,因为读第一行时默认还是以空格键分割 (--感觉是个缺陷呀)

解决方法:预先设置awk变量,利用BEGIN关键词

[root@localhost ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $3<10 {print $1 "	" $3}'
root	0
bin	1
daemon	2
adm	3
lp	4
sync	5
shutdown	6
halt	7
mail	8
[root@localhost ~]# awk  '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

[root@localhost ~]# awk -F: '/root/ {print $7}' /etc/passwd  //-F: 等效于FS=":"
/bin/bash
/sbin/nologin
  • 统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容
[root@localhost ~]# awk  -F ':'  '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd | head -n 5
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
  • 使用printf替代print,可以让代码更加简洁,易读
[root@localhost ~]# awk -F: '{printf ("filename:%10s, linenumber:%3s,column:%3s,content:%4s
",FILENAME,NR,NF,$0)}' /etc/passwd | head -n 5
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
  • 打印/etc/passwd/的第二行信息
[root@localhost ~]# awk -F: 'NR==2{print "filename: "FILENAME, $0}' /etc/passwd
filename: /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologin
  • 指定特定的分隔符,查询第一列
[root@localhost ~]# awk -F ":" '{print $1}' /etc/passwd | head -n 8
root
bin
daemon
adm
lp
sync
shutdown
halt
  • 指定特定的分隔符,查询最后一列
[root@localhost ~]# awk -F ":" '{print $NF}' /etc/passwd | tail -n 5
/bin/bash
/bin/bash
/bin/bash
/bin/bash
/sbin/nologin
  • 指定特定的分隔符,查询倒数第二列
[root@localhost ~]# awk -F ":" '{print $(NF-1)}' /etc/passwd | head -n 5
/root
/bin
/sbin
/var/adm
/var/spool/lpd
  • 获取第12到31行的第一列的信息
[root@localhost ~]# awk -F ":"  '{if(NR<31 && NR >12) print $1}' /etc/passwd
nobody
systemd-network
dbus
polkitd
libstoragemgmt
colord
rpc
saslauth
abrt
setroubleshoot
rtkit
radvd
gluster
chrony
qemu
unbound
tss
usbmuxd
  • 多分隔符的使用 (这里以/为分隔符,多个分隔符利用[]然后在里面写分隔符即可 )
[root@localhost ~]#  awk -F "[/]" 'NR == 4 {print $0,"
",$1}' /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin 
 adm:x:3:4:adm:
生活是一首长长的歌!
原文地址:https://www.cnblogs.com/wind-zhou/p/12829192.html