Linux三剑客之awk
awk是一个强大的linux命令,有强大的文本格式化能力,好比将一些文本数据格式化成装也的excel表的样式.awk更是一门编程语言,支持条件判断,数组,循环的能力
~ grep: 更擅长单纯的查找或匹配文本内容
~awk: 更适合编辑,处理匹配到的文本内容
~ sed: 更适合格式化文本内容,对文本进行复杂的处理
awk基础
awk语法
awk [option] ‘pattern’ [action] file…
awk 可选参数 模式 动作 文件/数据
~ action指的是动作,awk擅长文本格式化,且输出格式化后的结果,因此最常用的动作就是print
和printf
awk场景
[root@master bash]# cat 01.sh
wqe eqwe qweqw
weqw dsad dasdas
wqe dasd dasdsa
dasd wqe dasd
dasd qwe dasd
[root@master bash]# awk '{print $1}' 01.sh
wqe
weqw
wqe
dasd
dasd
[root@master bash]# awk '{print $0}' 01.sh
wqe eqwe qweqw
weqw dsad dasdas
wqe dasd dasdsa
dasd wqe dasd
dasd qwe dasd
我们执行的命令awk ‘{print $1}’,没有使用参数和模式,$1表示输出文本的第一列信息
awk默认以空格为分隔符,且多个空格也识别为一个空格,作为分隔符.
awk是按行处理文件,一行处理完毕,处理下一行,根据用户的分隔符去工作,没有指定分隔符则默认空格作为分隔符.
指定了分隔符后,awk把每一行分割的数据对应到内置变量
-$0表示整行
-$NF表示当前分割后的最后一列
-倒数第二列可以表示为$(NF-1)
awk内置变量
内置变量 解释 | |
---|---|
$n 指定分隔符后,当前记录的第n个字段 | |
$0 完整的输入记录 | |
FS 字段分隔符,默认为空格 | |
NF(Number of fieids) 分割后,当前一行有多少字段 | |
NR 当前记录数,行数 |
一次性输出多列信息
[root@master bash]# awk '{print $1,$3}' 01.sh
wqe qweqw
weqw dasdas
wqe dasdsa
dasd dasd
dasd dasd
注意当输出多列消息时,一般需要带上"," 这样输出信息时才会把输出的每列信息分开,如上图所示.
自定义输出内容
[root@master bash]# awk '{print "第一列:"$1,"第三列:"$3}' 01.sh
第一列:wqe 第三列:qweqw
第一列:weqw 第三列:dasdas
第一列:wqe 第三列:dasdsa
第一列:dasd 第三列:dasd
第一列:dasd 第三列:dasd
注意内置必要用"" ,外面只能用’'.
[root@master bash]# awk '{print}' 01.sh
wqe eqwe qweqw
weqw dsad dasdas
wqe dasd dasdsa
dasd wqe dasd
dasd qwe dasd
‘{print}‘等于’{print $0}’
awk参数
-F 指定分割字段符 | |
---|---|
-v 定义或修改一个awk内部的变量 | |
-f 从脚本文件中读取awk命令 |
显示文件第2-4行
[root@master bash]# awk 'NR==2{print $0}' 01.sh
weqw dsad dasdas
打印第二行的所有列信息
[root@master bash]# awk 'NR==2,NR==4{print $0}' 01.sh
weqw dsad dasdas
wqe dasd dasdsa
dasd wqe dasd
将行号也打印出来
[root@master bash]# awk '{print NR,$0}' 01.sh
1 wqe eqwe qweqw
2 weqw dsad dasdas
3 wqe dasd dasdsa
4 dasd wqe dasd
5 dasd qwe dasd
案例 以/etc/passwd文件为例,打印第20-25行的内容并显示行号
[root@master bash]# awk 'NR==20,NR==25{print NR,$0 }' passwd
20 gluster:x:996:993:GlusterFS daemons:/run/gluster:/sbin/nologin
21 qemu:x:107:107:qemu user:/:/sbin/nologin
22 rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
23 saslauth:x:995:76:Saslauthd user:/run/saslauthd:/sbin/nologin
24 libstoragemgmt:x:994:990:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
25 dnsmasq:x:988:988:Dnsmasq DHCP and DNS server:/var/lib/dnsmasq:/sbin/nologin
案例 以/etc/passwd文件为例,打印第20-24行的第一列,倒数第二列,倒数第三列(空格为分隔符)
[root@master bash]# awk 'NR==20,NR==24{print NR,$1,$(NF-1),$(NF-2)}' passwd
20 gluster:x:996:993:GlusterFS gluster:x:996:993:GlusterFS gluster:x:996:993:GlusterFS daemons:/run/gluster:/sbin/nologin
21 qemu:x:107:107:qemu qemu:x:107:107:qemu qemu:x:107:107:qemu user:/:/sbin/nologin
22 rpc:x:32:32:Rpcbind rpc:x:32:32:Rpcbind rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
23 saslauth:x:995:76:Saslauthd saslauth:x:995:76:Saslauthd saslauth:x:995:76:Saslauthd user:/run/saslauthd:/sbin/nologin
24 libstoragemgmt:x:994:990:daemon for account
awk分隔符
打印ip地址 (取最后一行ip地址)(以分隔符为空格取)
[root@master bash]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:c0:1d:c0 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.136/24 brd 192.168.1.255 scope global dynamic noprefixroute ens160
命令
[root@master bash]# ip a | awk 'NR==11{print $2}'
192.168.1.111/24
案例:以/etc/passwd文件为例,打印第1-5行的第一列,倒数第二列,倒数第三列(:为分隔符)
[root@master bash]# awk -F ":" 'NR==1,NR==5{print $1,$(NF-1),$(NF-2)}' passwd
root /root root
bin /bin bin
daemon /sbin daemon
adm /var/adm adm
lp /var/spool/lpd lp
或者
[root@master bash]# awk -v FS=":" 'NR==1,NR==5{print $1,$(NF-1),$(NF-2)}' passwd
root /root root
bin /bin bin
daemon /sbin daemon
adm /var/adm adm
lp /var/spool/lpd lp
OFS 输出符(默认输出符为空格)
以/etc/passwd文件为例,打印第1-5行的第一列,倒数第二列,倒数第三列(:为分隔符)打印输出符为:
[root@master bash]# awk -v FS=":" -v OFS=":" 'NR==1,NR==5{print $1,$(NF-1),$(NF-2)}' passwd
root:/root:root
bin:/bin:bin
daemon:/sbin:daemon
adm:/var/adm:adm
lp:/var/spool/lpd:lp