2019-06-28 21:24:00 ansheng0239 阅读数 0
  • Linux系统目录及必备命令学习

    通过本课程的学习,大家可以从懵懂到熟悉,从熟悉到熟练,能够在企业中熟练运用,同时在学习的过程中有任何不明白的地方,都可以向我咨询,我会积极帮助大家解决问题。

    4292课时 0分钟 217人学习 吴光科
    免费试看

#!bin/bash
#功能:使用awk提取Linux主机的参数信息,如内容剩余容量,根分区剩余容量,本机IP,本机能登录的用户个数,CPU负载.
#作者:liusingbon
#使用awk提取内存剩余容量
df -h | awk '/\//{print $4}'
#使用awk提取内存剩余容量
free -h | awk '/Mem/{print $4}'
#使用awk提取cpu负载信息
uptime | awk '{print $10}'
#使用awk提取本机IP地址
ifconfig eth0 | awk '/inet/{print $2}' | sed '2,+1d'
#使用awk提取本机能登录的用户个数
awk -F: '/bash$/{x++} END{print "本机能登录的用户量:",x}'  /etc/passwd

转载于:https://www.cnblogs.com/liusingbon/p/11104868.html

2019-06-04 21:16:01 LYJ_man 阅读数 1068
  • Linux系统目录及必备命令学习

    通过本课程的学习,大家可以从懵懂到熟悉,从熟悉到熟练,能够在企业中熟练运用,同时在学习的过程中有任何不明白的地方,都可以向我咨询,我会积极帮助大家解决问题。

    4292课时 0分钟 217人学习 吴光科
    免费试看

问题
本案例要求使用awk工具完成下列过滤任务:
练习awk工具的基本用法
提取本机的IP地址、根分区使用率
格式化输出/etc/passwd文件中的用户名、UID、宿主目录信息
格式化输出passwd文件内容时,要求第一行为列表标题,最后一行提示一共已处理文本的总行数,如图-1所示。
在这里插入图片描述
图-1
步骤
实现此案例需要按照如下步骤进行。
步骤一: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.
2019-06-03 08:11:47 iT__SuperMan 阅读数 370
  • Linux系统目录及必备命令学习

    通过本课程的学习,大家可以从懵懂到熟悉,从熟悉到熟练,能够在企业中熟练运用,同时在学习的过程中有任何不明白的地方,都可以向我咨询,我会积极帮助大家解决问题。

    4292课时 0分钟 217人学习 吴光科
    免费试看

1.使用awk提取文本
问题
本案例要求使用awk工具完成下列过滤任务:
练习awk工具的基本用法
提取本机的IP地址、根分区使用率
格式化输出/etc/passwd文件中的用户名、UID、宿主目录信息
格式化输出passwd文件内容时,要求第一行为列表标题,最后一行提示一共已处理文本的总行数,如图-1所示。
在这里插入图片描述
图-1
步骤
实现此案例需要按照如下步骤进行。
步骤一: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❌0:0:root:/root:/bin/bash
bin❌1:1:bin:/bin:/sbin/nologin
daemon❌2:2:daemon:/sbin:/sbin/nologin
adm❌3:4:adm:/var/adm:/sbin/nologin
lp❌4:7:lp:/var/spool/lpd:/sbin/nologin
sync❌5:0:sync:/sbin:/bin/sync
shutdown❌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❌0:0:root:/root:/b
b :/b
daemon❌2:2:daemon:/sb /nolog
adm❌3:4:adm:/var/adm:/sb
lp❌4:7:lp:/var/spool/lpd:/sb
sync❌5:0:sync:/sb /sync
shutdown❌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: ‘$1ENVIRON[“USER”]{print $0}’ passwd.txt
root❌0:0:root:/root:/bin/bash //输出当前用户的记录
注意:$0表示正在处理的整行文本,可以省略(默认即输出整行);当编辑指令是输出匹配的整行文本时,整个{print $0}都可以不写。
上述操作可简写为:
[root@svr5 ~]# awk -F: '$1
ENVIRON[“USER”]{print}’ passwd.txt
root❌0:0:root:/root:/bin/bash
或者:
[root@svr5 ~]# awk -F: ‘KaTeX parse error: Expected 'EOF', got '#' at position 289: …: [root@svr5 ~]#̲ awk 'BEGIN{A=1…/{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.

2019-08-31 16:30:59 m0_38039437 阅读数 1621
  • Linux系统目录及必备命令学习

    通过本课程的学习,大家可以从懵懂到熟悉,从熟悉到熟练,能够在企业中熟练运用,同时在学习的过程中有任何不明白的地方,都可以向我咨询,我会积极帮助大家解决问题。

    4292课时 0分钟 217人学习 吴光科
    免费试看

awk提取指定json的数据

  1 #!/bin/bash
  2 #需要处理的数据
  3 name={"code":200,"success":true,"result":"86f8069971e87fa1"}
  4 echo "处理前的数据"
  5 echo $name
  6 echo "awk对数据进行处理"
  7 #使用多次分割方式获取到需要的数据,并将结果赋值给变量
  8 vars=`echo $name | awk -F':' '{print $NF}'|awk -F "}" '{print $1}'`
  9 #输出awk处理后的数据
 10 echo $vars

awk -F 是指定分割符

2019-05-22 10:09:29 weixin_44792728 阅读数 692
  • Linux系统目录及必备命令学习

    通过本课程的学习,大家可以从懵懂到熟悉,从熟悉到熟练,能够在企业中熟练运用,同时在学习的过程中有任何不明白的地方,都可以向我咨询,我会积极帮助大家解决问题。

    4292课时 0分钟 217人学习 吴光科
    免费试看
  1. 使用awk提取文本
  • 问题

本案例要求使用awk工具完成下列过滤任务:

  • 练习awk工具的基本用法
  • 提取本机的IP地址、根分区使用率
  • 格式化输出/etc/passwd文件中的用户名、UID、宿主目录信息

格式化输出passwd文件内容时,要求第一行为列表标题,最后一行提示一共已处理文本的总行数,如图-1所示。

-1

  • 步骤

实现此案例需要按照如下步骤进行。

步骤一: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.

  1. awk处理条件
  • 问题

本案例要求使用awk工具完成下列过滤任务,注意awk处理条件的设置:

  • 列出UID间于501~505的用户详细信息
  • 输出/etc/hosts文件内以127或192开头的记录
  • 列出100以内整数中7的倍数或是含7的数
  • 步骤

实现此案例需要按照如下步骤进行。

步骤一:认识awk处理条件的设置

创建测试文件passwd.txt文件:

[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

1)使用正则表达式设置条件

输出其中以bash结尾的完整记录:

[root@svr5 ~]# awk -F: '/bash$/{print}' passwd.txt

root:x:0:0:root:/root:/bin/bash

输出以a、b、c或d开头的用户名、宿主目录:

[root@svr5 ~]# awk -F: '/^[a-d]/{print $1,$6}' passwd.txt

bin /bin

daemon /sbin

adm /var/adm

输出其中用户名以a开头、登录Shell以nologin结尾的用户名、登录Shell:

[root@svr5 ~]# awk -F: '/^a|nologin$/{print $1,$7}' passwd.txt

bin /sbin/nologin

daemon /sbin/nologin

adm /sbin/nologin

lp /sbin/nologin

输出其中宿主目录以bin结尾(对第6个字段做~匹配)的用户名、宿主目录信息:

[root@svr5 ~]# awk -F: '$6~/bin$/{print $1,$6}' passwd.txt

bin /bin

daemon /sbin

sync /sbin

shutdown /sbin

输出其中登录Shell不以nologin结尾(对第7个字段做!~反向匹配)的用户名、登录Shell信息:

[root@svr5 ~]# awk -F: '$7!~/nologin$/{print $1,$7}' passwd.txt

root /bin/bash

sync /bin/sync

shutdown /sbin/shutdown

2)使用数值/字符串比较设置条件

输出第3行(行号NR等于3)的用户记录:

[root@svr5 ~]# awk -F: 'NR==3{print}' passwd.txt

daemon:x:2:2:daemon:/sbin:/sbin/nologin

输出奇数行(行号NR除以2余数为1)的用户记录:

[root@svr5 ~]# awk -F: 'NR%2==1{print}' passwd.txt

root:x:0:0:root:/root:/bin/bash

daemon:x:2:2:daemon:/sbin:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

输出偶数行(行号NR除以2余数为0)的用户记录:

[root@svr5 ~]# awk -F: 'NR%2==0{print}' passwd.txt

bin:x:1:1:bin:/bin:/sbin/nologin

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

sync:x:5:0:sync:/sbin:/bin/sync

输出前3行文本:

[root@svr5 ~]# awk -F: 'NR<=3{print}' 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

输出从第5行开始到文件末尾的所有行:

[root@svr5 ~]# awk -F: 'NR>=5{print}' passwd.txt

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

输出用户名为“sync”的行:

[root@svr5 ~]# awk -F: '$1=="sync"{print}' passwd.txt

sync:x:5:0:sync:/sbin:/bin/sync

输出当前用户的用户名、宿主目录、登录Shell信息:

[root@svr5 ~]# awk -F: '$1==ENVIRON["USER"]{print $1,$6,$7}' passwd.txt

root /root /bin/bash

3)逻辑测试条件

输出第3~5行文本:

[root@svr5 ~]# awk -F: 'NR>=3&&NR<=5{print}' passwd.txt

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

严谨一点可以写成:

[root@svr5 ~]# awk -F: '(NR>=3)&&(NR<=5){print}' passwd.txt

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

输出第3行和第5行文本:

[root@svr5 ~]# awk -F: 'NR==3||NR==5{print}' passwd.txt

daemon:x:2:2:daemon:/sbin:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

输出“登录Shell不以nologin结尾”或者“用户名以a或d开头”的文本:

[root@svr5 ~]# awk -F: '$7!~/nologin$/||$1~/^[ad]/{print}' passwd.txt

root:x:0:0:root:/root:/bin/bash

daemon:x:2:2:daemon:/sbin:/sbin/nologin

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

sync:x:5:0:sync:/sbin:/bin/sync

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

输出UID小于3或者UID是偶数的用户记录:

[root@svr5 ~]# awk -F: '$3<3||$3%2==0{print}' 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

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

4)数学运算

以统计passwd.txt文件中以“:”分隔的总字段个数,需要每处理一行时将当前行的字段数(内置变量NF)计和,因此可在BEGIN时定义一个初始变量,过程称求和,最后在END时输出结果。

相关操作及结果如下(共49个字段):

[root@svr5 ~]# awk -F: 'BEGIN{x=0}\

 {x+=NF} END{print "Total "x" fields."}' passwd.txt

Total 49 fields.

步骤二:完成任务要求的awk过滤操作

1)列出UID间于501~505的用户详细信息:

[root@svr5 ~]# awk -F: '$3>=501&&$3<=505{print}' /etc/passwd

hunter:x:501:501::/home/hunter:/bin/bash

vina:x:502:502::/home/vina:/bin/bash

kdev:x:503:503::/home/kdev:/bin/bash

zengye:x:504:504::/home/zengye:/bin/bash

stu01:x:505:1201::/tech/nsdhome/stu01:/bin/bash

2)输出/etc/hosts映射文件内以127或者192开头的记录:

[root@svr5 ~]# awk -F: '/^127|^192/{print}' /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

192.168.4.5  svr5.tarena.com svr5

3)列出100以内整数中7的倍数或是含7的数:

此操作无处理文件,正常思路应该是用Shell循环来完成;因为要求用awk来实现,如果不用循环,则根据逐行处理的思路,应该提供一个100行的文本对象,然后将行号作为处理的整数,逐个判断并输出即可。

利用seq命令可生成1-100的整数序列,比如:

[root@svr5 ~]# seq 100

1

2

3

4

5

6

7

8

9

10

.. ..

91

92

93

94

95

96

97

98

99

100

结合管道交给awk处理,可以简化实现步骤。针对本任务而言,行号与每行的实际文本值是一致的,那么根据NR或者$0行值进行判断都是可以的。输出100以内7的倍数或是包含7的数:

[root@svr5 ~]# seq 100 | awk 'NR%7==0||NR~/7/{print}'

7

14

17

21

27

28

35

37

42

47

.. ..

75

76

77

78

79

84

87

91

97

98

或者:

[root@svr5 ~]# seq 100 | awk '$0%7==0||$0~/7/{print}'

7

14

17

21

27

28

35

37

42

47

.. ..

75

76

77

78

79

84

87

91

97

98

  1. awk综合脚本应用
  • 问题

本案例要求编写脚本getupwd-awk.sh,实现以下需求:

  • 找到使用bash作登录Shell的本地用户
  • 列出这些用户的shadow密码记录
  • 按每行“用户名 --> 密码记录”保存到getupwd.log,如图-2所示

图-2

  • 步骤

实现此案例需要按照如下步骤进行。

步骤一:任务需求及思路分析

编写getupwd-awk.sh脚本的任务要求如下:

  • 分析出使用bash作登录Shell的本地用户
  • 列出这些用户的shadow密码记录
  • 按每行“用户名 -- 密码记录”保存结果

上一章实现时基本是用sed来过滤,结合变量替换截取来实现的,操作比较繁琐。

现在学习了awk以后,再想想这个任务要求,是不是变简单了?

—— 提取用户名列表时,只要通过awk命令以“:”为分隔提取/etc/passwd文件中结尾部分为“:/bin/bash”的用户记录的第1个字段即可。

—— 有了用户名列表以后,可以交给for循环做一个遍历,egrep提取密码行,再交给awk提取以“:”分隔的第3个字段即可。

步骤二:根据实现思路编写脚本

复制原getupwd.sh脚本,生成getupwd-awk.sh:

[root@svr5 ~]# cat getupwd.sh   //确认原脚本内容

#/bin/bash

> /tmp/getupwd.log                      ## 创建空文件

sed -n '/:\/bin\/bash$/w /tmp/urec.tmp' /etc/passwd   ## 提取符合条件的账号记录

UNUM=$(egrep -c '.' /tmp/urec.tmp)    ## 取得记录个数

while [ ${i:=1} -le $UNUM ]      ## 从第1行开始,遍历账号记录

do

    UREC=$(sed -n "${i}p" /tmp/urec.tmp)   ## 取指定行数的记录

    NAME=${UREC%%:*}          ## 截取用户名(记录去尾)

    PREC=$(sed -n "/^$NAME:/p" /etc/shadow)   ## 查找与用户名对应的密码记录

    PASS=${PREC#*:}           ## 掐头

    PASS=${PASS%%:*}             ## 去尾,只留下密码记录

    echo "$NAME --> $PASS" >> /tmp/getupwd.log ## 保存结果

    let i++                    ## 自增1,转下一次循环

done

/bin/rm -rf /tmp/urec.tmp            ## 删除临时文件

echo "用户分析完毕,请查阅文件 /tmp/getupwd.log" ## 完成后提示

 

[root@svr5 ~]# cp getupwd.sh getupwd-awk.sh   //复制为新脚本文件

修改新脚本文件,内容参考如下:

[root@svr5 ~]# vim getupwd-awk.sh

#/bin/bash

## 创建空文件

> /tmp/getupwd.log

## 提取用户名列表

awk -F: '/:\/bin\/bash$/{print $1}' /etc/passwd > /tmp/users.tmp

## 通过for循环遍历用户名、查询密码记录,保存结果

for NAME in $(cat /tmp/users.tmp)

do

    grep "^$NAME:" /etc/shadow | awk -F: '{print $1" --> "$2 | \

    "cat >> /tmp/getupwd.log"}' /etc/shadow

done

echo "用户分析完毕,请查阅文件 /tmp/getupwd.log" ## 完成后提示

 

[root@svr5 ~]# chmod +x getupwd-awk.sh

步骤三:验证、测试脚本

[root@svr5 ~]# ./getupwd-awk.sh      

用户分析完毕,请查阅文件 /tmp/getupwd.log

 

[root@svr5 ~]# head -5 /tmp/getupwd.log

root --> $6$IWgMYmRACwdbfwBo$dr8Yn983nswiJVw0dTMjzbDvSLeCd1GMYjbvsDiFEkL8jnXOLcocBQypOCr4C6BRxNowIxjh6U2qeFU0u1LST/

zengye --> $6$Qb37LOdzRl5995PI$L0zTOgnhGz8ihWkW81J.5XhPp/l7x2./Me2ag0S8tRndCBL9nIjHIKkUKulHxJ6TXyHYmffbVgUT6pbSwf8O71

clamav --> !!

mysql --> !!

abc --> !!

.. ..

 

  1. awk流程控制
  • 问题

本案例要求了解awk的流程控制操作,可自行设置awk语句来有验证以下操作:

  • if分支结构(双分支、多分支)
  • while/for循环结构
  • break、continue、next等其他控制语句
  • 步骤

实现此案例需要按照如下步骤进行。

步骤一:awk过滤中的if分支结构

1)单分支

统计/etc/passwd文件中UID小于或等于500的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0}{if($3<=500){i++}}END{print i}' /etc/passwd

39

统计/etc/passwd文件中UID大于500的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0}{if($3>500){i++}}END{print i}' /etc/passwd

28

统计/etc/passwd文件中登录Shell是“/bin/bash”的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0}{if($7~/bash$/){i++}}END{print i}'\

 /etc/passwd

29

统计/etc/passwd文件中登录Shell不是“/bin/bash”的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0}{if($7!~/bash$/){i++}}END{print i}'\

 /etc/passwd

38

2)双分支

分别统计/etc/passwd文件中UID小于或等于500、UID大于500的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0;j=0}{if($3<=500){i++}else{j++}}END{print i,j}' /etc/passwd

39 28

分别统计/etc/passwd文件中登录Shell是“/bin/bash”、 登录Shell不是“/bin/bash”的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0;j=0}{if($7~/bash$/){i++}else{j++}}\

END{print i,j}' /etc/passwd

29 38

3)多分支

分别统计/etc/passwd文件中登录Shell是“/bin/bash”、“/sbin/nologin”、其他的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0;j=0;k=0}{if($7~/bash$/){i++}\

else if($7~/nologin$/){j++}else{k++}}END{print i,j,k}' /etc/passwd

29 33 5

步骤二:awk过滤中的while/for循环结构

1)while循环

统计/etc/passwd文件内“root”出现的次数。

—— 分析:以“:”或“/”做分隔,针对每一行的每一列进行比对,如果包含“root”,则次数加1。其中,逐行处理直接由awk完成,逐列处理交给while循环,通过i变量依次取$1、$2、……、$NF进行检查;变量j在预处理时赋值0,没匹配一个字段加1。

[root@svr5 ~]# awk -F [:/] \

'BEGIN{j=0}\

{i=1}{while(i<=NF){if($i~/root/){j++};i++}}\

END{print j}'  /etc/passwd

4

此例仅为说明while循环的用法。

实际应用时,上述操作可以简单处理,可通过命令替换将文件内容赋值给一个变量(变为一行文本),然后针对此变量值以目标字符串“root”作为分隔,获取总字段数-1即可得目标字符串的总数量:

[root@svr5 ~]# echo $(cat /etc/passwd) | awk -F "root" '{print NF-1}'

4

2)for循环

类似于Shell中C风格的for循环,基本格式如下:

for(初值;条件;步长){编辑指令}

比如,输出从1~10之间的整数:

[root@svr5 ~]# awk 'BEGIN{for(i=1;i<=10;i++){print i}}'

1

2

3

4

5

6

7

8

9

10

输出从1~20之间所有的3的倍数:

[root@svr5 ~]# awk 'BEGIN{for(i=1;i<=20;i++){if(i%3==0){print i}}}'

3

6

9

12

15

18

计算从1~100内各整数的总和:

[root@svr5 ~]# awk 'BEGIN{for(i=1;i<=100;i++){sum+=i;\

if(i==100){print sum}}}'

5050

步骤三:awk过滤中的其他控制结构

/etc/rc.local文件为例,确认文件内容如下:

[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

使用next可跳过当前行。比如,输出文件中超过2个字段(默认分隔)的行:

[root@svr5 ~]# awk 'NF<=2{next}{print}' /etc/rc.local

# 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.

上述操作的效果等同于:

[root@svr5 ~]# awk 'NF>2{print}' /etc/rc.local

# 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.

  1. awk扩展应用
  • 问题

本案例要求使用awk工具完成下列两个任务:

  • 去除文件重复行:提取/etc/passwd文件的第7列,保存为a1.txt;然后排除a1.txt文件的重复行,将结果另存为a2.txt 
  • 分析Web日志的访问量排名,要求获得客户机的地址、访问次数,并且按照访问次数排名
  • 方案

1)awk经典去重

基本用法:awk '!a[$0]++'  filename 。

其中a为数组名,$0为处理对象,表示要去除的是“整行重复”的内容;如果要去除的是“字段重复”的行,可以将$0更改为$1、$2等相应字段。

a[$0]++操作将整行内容作为a数组的下标,当遇到陌生行(第一次出现)的时候,数组元素a[$0]还不存在,因此++操作会失败,通过!取反后则条件成立,从而按照默认的print指令(上述用法中省略了{print})输出当前行的内容。

当遇到已知的行(第二、三、……次出现)的时候,数组元素a[$0]已经存在,因此++操作会成功,通过!取反后则条件不成立,从而忽略了当前行的内容——也就是说,重复的行被跳过去了。

2)awk统计Web访问排名

在分析Web日志文件时,每条访问记录的第一列就是客户机的IP地址,其中会有很多重复的IP地址。因此只用awk提取出这一列是不够的,还需要统计重复记录的数量并且进行排序。

通过awk提取信息时,利用IP地址作为数组下标,每遇到一个重复值就将此数组元素递增1,最终就获得了这个IP地址出现的次数。

针对文本排序输出可以采用sort命令,相关的常见选项为-r、-n、-k。其中-n表示按数字顺序升序排列,而-r表示反序,-k可以指定按第几个字段来排序。

  • 步骤

实现此案例需要按照如下步骤进行。

步骤一:去除文件重复行

1)提取测试文件

[root@svr5 ~]# awk -F: '{print $7}' /etc/passwd > a1.txt

[root@svr5 ~]# cat a1.txt

/bin/bash

/sbin/nologin

/sbin/nologin

/sbin/nologin

/sbin/nologin

/bin/sync

/sbin/shutdown

/sbin/halt

/sbin/nologin

/sbin/nologin

.. ..

[root@svr5 ~]#

2)去除a1.txt文件中的重复行,另存为a2.txt

[root@svr5 ~]# awk '!a[$0]++' a1.txt  > a2.txt

[root@svr5 ~]# cat a2.txt

/bin/bash

/sbin/nologin

/bin/sync

/sbin/shutdown

/sbin/halt

[root@svr5 ~]#

步骤二:统计Web访问量排名

分步测试、验证效果如下所述。

1)提取IP地址及访问量

[root@svr5 ~]# awk  '{ip[$1]++} END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log

127.0.0.1 4

192.168.4.5 17

192.168.4.110 13

.. ..

2)对第1)步的结果根据访问量排名

[root@svr5 ~]# awk  '{ip[$1]++} END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log | sort -nr -k 2

192.168.4.5 17

192.168.4.110 13

127.0.0.1 4

.. ..