系统相关
首页 > 系统相关> > Linux shell 编程 之awk的使用

Linux shell 编程 之awk的使用

作者:互联网

使用awk提取文本

步骤一:awk文本过滤的基本用法
1)基本操作方法
格式:awk [选项] ‘[条件]{编辑指令}’ 文件
其中,print 是最常用的编辑指令;若有多条编辑指令,可用分号分隔。
处理文本时,若未指定分隔符,则默认将空格、制表符等作为分隔符。
直接过滤文件内容:

[root@svr5 ~]# cat /etc/rc.local  					//文件的完整内容
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local
[root@svr5 ~]# awk '{print $1,$2}' /etc/rc.local  	//输出文件的第1、2列
#!/bin/sh
#
# This
# You
# want

touch /var/lock/subsys/local

结合管道过滤命令输出:

[root@svr5 ~]# uname -a  							//正常的完整输出
Linux svr5.tarena.com 2.6.18-348.el5 #1 SMP Wed Nov 28 21:22:00 EST 2012 x86_64 x86_64 x86_64 GNU/Linux
[root@svr5 ~]# uname -a | awk '{print $1,$3,$12}'  	//输出第1、3、12字段
Linux 2.6.18-348.el5 x86_64

2)选项 -F 可指定分隔符
截取/etc/passwd文件的前7行,用来创建一个测试文件,操作如下:

[root@svr5 ~]# head -7 /etc/passwd > passwd.txt
[root@svr5 ~]# cat passwd.txt
root:x:0:0:root:/root:/bin/bash
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

输出passwd.txt文件中以分号分隔的第1、7个字段,显示的不同字段之间以逗号隔开,操作如下:

[root@svr5 ~]# awk -F: '{print $1","$7}' passwd.txt
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown

或者:

[root@svr5 ~]# awk -F ":" '{print $1","$7}' passwd.txt
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown

awk过滤处理也支持以指定的字符串作为分隔,比如以“in”分隔,输出第1、3个字段的文本:

[root@svr5 ~]# awk -F "in" '{print $1,$3}' passwd.txt
root:x:0:0:root:/root:/b
b :/b
daemon:x:2:2:daemon:/sb /nolog
adm:x:3:4:adm:/var/adm:/sb
lp:x:4:7:lp:/var/spool/lpd:/sb
sync:x:5:0:sync:/sb /sync
shutdown:x:6:0:shutdown:/sb /shutdown

awk还识别多种单个的字符,比如以“:”或“/”分隔,输出第1、10个字段:

[root@svr5 ~]# awk -F [:/] '{print $1,$10}' passwd.txt
root bash
bin nologin
daemon nologin
adm sbin
lp
sync sync
shutdown shutdown

3)特殊的内置变量
注意:调用awk的内置变量时,不需要加前置 $ 符号。
比如,使用awk输出当前操作的文件名、当前处理的行号:

[root@svr5 ~]# awk '{print FILENAME,NR}' passwd.txt
passwd.txt 1
passwd.txt 2
passwd.txt 3
passwd.txt 4
passwd.txt 5
passwd.txt 6
passwd.txt 7

输出每次处理的行号,以及当前行以“:”分隔的字段个数:

[root@svr5 ~]# awk -F: '{print NR,NF}' passwd.txt
1 7
2 7
3 7
4 7
5 7
6 7
7 7

输出当前用户的passwd记录(第1列的值与系统变量USER的值相同):

[root@svr5 ~]# echo $USER  						//确认当前用户
root
[root@svr5 ~]# awk -F: '$1==ENVIRON["USER"]{print $0}' passwd.txt
root:x:0:0:root:/root:/bin/bash  					//输出当前用户的记录

注意:$0表示正在处理的整行文本,可以省略(默认即输出整行);当编辑指令是输出匹配的整行文本时,整个{print $0}都可以不写。
上述操作可简写为:

[root@svr5 ~]# awk -F: '$1==ENVIRON["USER"]{print}' passwd.txt      
root:x:0:0:root:/root:/bin/bash
或者:
[root@svr5 ~]# awk -F: '$1==ENVIRON["USER"]' passwd.txt       
root:x:0:0:root:/root:/bin/bash

4)awk处理的时机
awk会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行之后做一些总结性质的工作。在命令格式上分别体现如下:
行前处理,BEGIN{ }
逐行处理,{ }
行后处理,END{ }
上述编辑指令段可以包含在一对单引号内,比如:
awk [选项] ’ BEGIN{编辑指令 } {编辑指令} END{编辑指令}’ 文件
只做预处理的时候,可以没有操作文件,比如:

[root@svr5 ~]# awk 'BEGIN{A=1024;print A*2.56}'
2621.44

举个包括三个处理时机的例子——“统计系统中使用bash作为登录Shell的用户总个数:预处理时赋值变量x=0,然后逐行读入/etc/passwd文件检查,如果发现登录Shell是/bin/bash则x增加1,全部处理完毕后,输出x的值即可。相关操作及结果如下:

[root@svr5 ~]# awk 'BEGIN{x=0}/\<bash$/{x++} END{print x}' /etc/passwd
29

当然,这个例子比较简单(效果与egrep -c ‘<bash$’ /etc/passwd 相同),此处仅仅是用来说明awk三种处理时机的用法。在实际工作中,利用awk的这种处理流程可以完成许多更复杂的任务。
步骤二:利用awk提取本机的IP地址、根分区使用率
1)提取IP地址
分步实现的思路及操作参考如下——
通过ifconfig eth0查看网卡信息,其中包括IP地址:

[root@svr5 ~]# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:0C:29:82:09:E9
          inet addr:192.168.4.4  Bcast:192.168.4.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe82:9e9/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:358524 errors:0 dropped:0 overruns:0 frame:0
          TX packets:230638 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:44470760 (42.4 MiB)  TX bytes:64236279 (61.2 MiB)

结合grep获得包含IP地址的那一行:

[root@svr5 ~]# ifconfig eth0 | grep "inet addr:"
          inet addr:192.168.4.4  Bcast:192.168.4.255  Mask:255.255.255.0

再结合awk过滤出默认分隔的第2列:

[root@svr5 ~]# ifconfig eth0 | grep "inet addr:" | awk '{print $2}'
addr:192.168.4.4

进一步结合awk过滤出以“:”分隔的第2列:

[root@svr5 ~]# ifconfig eth0 | grep "inet addr:" | awk '{print $2}' | awk -F: '{print $2}'
192.168.4.4

2)提取根分区使用率
分步实现的思路及操作参考如下——
通过df命令查看根分区的使用情况,其中包括使用率:

[root@svr5 ~]# df -hT /
文件系统 		类型 	容量 	已用 	可用 	已用% 	挂载点
/dev/sda2 	ext3 	19G 		7.2G 	11G 		40% 		/

输出上述结果中最后一行的第6列:

[root@svr5 ~]# df -hT / | tail -1 | awk '{print $6}'
40%

步骤三:格式化输出/etc/passwd文件
1)任务需求及实现思路分析
根据任务要求的结果,输出的内容包括三个部分:列表头、用户信息、列表尾。
由于/etc/passwd文件中的用户记录是单一的以“:”分隔,而且恰好awk本身就已经支持“前、中、后”三段式处理,所以用awk处理是再合适不过了。通过awk的内置变量NR即可获得处理的记录行数,因此只要设置正确的输出即可。
2)根据实现思路编写、验证awk过滤语句
输出信息时,可以使用“\t”显示Tab制表位:

[root@svr5 ~]# awk -F: 'BEGIN{print "User\tUID\tHome"} \
{print $1"\t"$3"\t"$6} END{print "Total "NR" lines."}' /etc/passwd
User    UID     Home
root    0       /root
bin     1       /bin
daemon  2       /sbin
adm     3       /var/adm
lp      4       /var/spool/lpd
sync    5       /sbin
.. ..
iamkiller       1234    /opt/.private/iamkiller
nsd001  0       /home/nsd001
nsd002  1236    /home/nsd002
nsd003  1237    /home/nsd003
postfix 89      /var/spool/postfix
Total 67 lines.

标签:sbin,shell,passwd,svr5,awk,Linux,print,root
来源: https://blog.csdn.net/Win_Le/article/details/90706397