awk应用

以後 以後     2022-10-09     467

关键词:

使用awk提取文本

1.1 问题

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

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

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

技术分享图片

图-1

1.2 步骤

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

步骤一:awk文本过滤的基本用法

1)基本操作方法

格式:awk [选项] ‘[条件]{编辑指令}‘ 文件

其中,print 是最常用的编辑指令;若有多条编辑指令,可用分号分隔。

处理文本时,若未指定分隔符,则默认将空格、制表符等作为分隔符。

直接过滤文件内容:

  1. [[email protected] ~]# awk ‘{print $1,$2}‘ /etc/rc.local     //输出文件的第1、2列
  2. #!/bin/sh
  3. #
  4. # This
  5. # You
  6. # want
  7. touch /var/lock/subsys/local

结合管道过滤命令输出:

  1. [[email protected] ~]# uname -a                             //正常的完整输出
  2. 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
  3. [[email protected] ~]# uname -a | awk ‘{print $1,$3,$12}‘     //输出第1、3、12字段
  4. Linux 2.6.18-348.el5 x86_64

2)选项 -F 可指定分隔符

截取/etc/passwd文件的前7行,用来创建一个测试文件,操作如下:

  1. [[email protected] ~]# head -7 /etc/passwd > passwd.txt
  2. [[email protected] ~]# cat passwd.txt
  3. root:x:0:0:root:/root:/bin/bash
  4. bin:x:1:1:bin:/bin:/sbin/nologin
  5. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  6. adm:x:3:4:adm:/var/adm:/sbin/nologin
  7. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  8. sync:x:5:0:sync:/sbin:/bin/sync
  9. shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

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

  1. [[email protected] ~]# awk -F: ‘{print $1","$7}‘ passwd.txt
  2. root,/bin/bash
  3. bin,/sbin/nologin
  4. daemon,/sbin/nologin
  5. adm,/sbin/nologin
  6. lp,/sbin/nologin
  7. sync,/bin/sync
  8. shutdown,/sbin/shutdown

或者:

  1. [[email protected] ~]# awk -F ":" ‘{print $1","$7}‘ passwd.txt
  2. root,/bin/bash
  3. bin,/sbin/nologin
  4. daemon,/sbin/nologin
  5. adm,/sbin/nologin
  6. lp,/sbin/nologin
  7. sync,/bin/sync
  8. shutdown,/sbin/shutdown

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

  1. [[email protected] ~]# awk -F [:/] ‘{print $1,$10}‘ passwd.txt
  2. root bash
  3. bin nologin
  4. daemon nologin
  5. adm sbin
  6. lp
  7. sync sync
  8. shutdown shutdown

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

  1. [[email protected] ~]# awk -F: ‘{print NR,NF}‘ passwd.txt
  2. 1 7
  3. 2 7
  4. 3 7
  5. 4 7
  6. 5 7
  7. 6 7
  8. 7 7

4)awk处理的时机

awk会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行之后做一些总结性质的工作。在命令格式上分别体现如下:

  • 行前处理,BEGIN{ }
  • 逐行处理,{ }
  • 行后处理,END{ }

上述编辑指令段可以包含在一对单引号内,比如:

  1. awk [选项] ‘ BEGIN{编辑指令 } {编辑指令} END{编辑指令}‘ 文件

只做预处理的时候,可以没有操作文件,比如:

  1. [[email protected] ~]# awk ‘BEGIN{A=1024;print A*2.56}‘
  2. 2621.44

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

  1. [[email protected] ~]# awk ‘BEGIN{x=0}/<bash$/{x++} END{print x}‘ /etc/passwd
  2. 29

当然,这个例子比较简单(效果与egrep -c ‘<bash$‘ /etc/passwd 相同),此处仅仅是用来说明awk三种处理时机的用法。在实际工作中,利用awk的这种处理流程可以完成许多更复杂的任务。

步骤二:利用awk提取本机的IP地址、根分区使用率

1)提取IP地址

分步实现的思路及操作参考如下——

通过ifconfig eth0查看网卡信息,其中包括IP地址:

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

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

  1. [[email protected] ~]# ifconfig eth0 | grep "inet"
  2. inet addr:192.168.4.4 Bcast:192.168.4.255 Mask:255.255.255.0

再结合awk过滤出第2列:

  1. [[email protected] ~]# ifconfig eth0 | grep "inet" | awk ‘{print $2}‘
  2. 192.168.4.4

2)提取根分区使用率

分步实现的思路及操作参考如下——

通过df命令查看根分区的使用情况,其中包括使用率:

  1. [[email protected] ~]# df -hT /
  2. 文件系统         类型     容量     已用     可用     已用%     挂载点
  3. /dev/sda2     ext3     19G         7.2G     11G         40%         /

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

  1. [[email protected] ~]# df -hT / | tail -1 | awk ‘{print $6}‘
  2. 40%

步骤三:格式化输出/etc/passwd文件

1)任务需求及实现思路分析

根据任务要求的结果,输出的内容包括三个部分:列表头、用户信息、列表尾。

由于/etc/passwd文件中的用户记录是单一的以“:”分隔,而且恰好awk本身就已经支持“前、中、后”三段式处理,所以用awk处理是再合适不过了。通过awk的内置变量NR即可获得处理的记录行数,因此只要设置正确的输出即可。

2)根据实现思路编写、验证awk过滤语句

输出信息时,可以使用“ ”显示Tab制表位:

  1. [[email protected] ~]# awk -F: ‘BEGIN{print "User UID Home"}
  2. {print $1" "$3" "$6} END{print "Total "NR" lines."}‘ /etc/passwd
  3. User UID Home
  4. root 0 /root
  5. bin 1 /bin
  6. daemon 2 /sbin
  7. adm 3 /var/adm
  8. lp 4 /var/spool/lpd
  9. sync 5 /sbin
  10. .. ..
  11. iamkiller 1234 /opt/.private/iamkiller
  12. nsd001 0 /home/nsd001
  13. nsd002 1236 /home/nsd002
  14. nsd003 1237 /home/nsd003
  15. postfix 89 /var/spool/postfix
  16. Total 67 lines.

2 案例2:awk处理条件

2.1 问题

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

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

2.2 步骤

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

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

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

  1. [[email protected] ~]# head -7 /etc/passwd > passwd.txt
  2. [ro[email protected] ~]# cat passwd.txt
  3. root:x:0:0:root:/root:/bin/bash
  4. bin:x:1:1:bin:/bin:/sbin/nologin
  5. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  6. adm:x:3:4:adm:/var/adm:/sbin/nologin
  7. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  8. sync:x:5:0:sync:/sbin:/bin/sync
  9. shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

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

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

  1. [[email protected] ~]# awk -F: ‘/bash$/{print}‘ passwd.txt
  2. root:x:0:0:root:/root:/bin/bash

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

  1. [[email protected] ~]# awk -F: ‘/^[a-d]/{print $1,$6}‘ passwd.txt
  2. bin /bin
  3. daemon /sbin
  4. adm /var/adm

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

  1. [[email protected] ~]# awk -F: ‘/^a|nologin$/{print $1,$7}‘ passwd.txt
  2. bin /sbin/nologin
  3. daemon /sbin/nologin
  4. adm /sbin/nologin
  5. lp /sbin/nologin

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

  1. [[email protected] ~]# awk -F: ‘$6~/bin$/{print $1,$6}‘ passwd.txt
  2. bin /bin
  3. daemon /sbin
  4. sync /sbin
  5. shutdown /sbin

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

  1. [[email protected] ~]# awk -F: ‘$7!~/nologin$/{print $1,$7}‘ passwd.txt
  2. root /bin/bash
  3. sync /bin/sync
  4. shutdown /sbin/shutdown

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

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

  1. [[email protected] ~]# awk -F: ‘NR==3{print}‘ passwd.txt
  2. daemon:x:2:2:daemon:/sbin:/sbin/nologin

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

  1. [[email protected] ~]# awk -F: ‘NR%2==1{print}‘ passwd.txt
  2. root:x:0:0:root:/root:/bin/bash
  3. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  4. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  5. shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

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

  1. [[email protected] ~]# awk -F: ‘NR%2==0{print}‘ passwd.txt
  2. bin:x:1:1:bin:/bin:/sbin/nologin
  3. adm:x:3:4:adm:/var/adm:/sbin/nologin
  4. sync:x:5:0:sync:/sbin:/bin/sync

输出前3行文本:

  1. [[email protected] ~]# awk -F: ‘NR<=3{print}‘ passwd.txt
  2. root:x:0:0:root:/root:/bin/bash
  3. bin:x:1:1:bin:/bin:/sbin/nologin
  4. daemon:x:2:2:daemon:/sbin:/sbin/nologin

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

  1. [[email protected] ~]# awk -F: ‘NR>=5{print}‘ passwd.txt
  2. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  3. sync:x:5:0:sync:/sbin:/bin/sync
  4. shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

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

  1. [[email protected] ~]# awk -F: ‘$1=="sync"{print}‘ passwd.txt
  2. sync:x:5:0:sync:/sbin:/bin/sync

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

  1. [[email protected] ~]# awk -F: ‘$1==ENVIRON["USER"]{print $1,$6,$7}‘ passwd.txt
  2. root /root /bin/bash

3)逻辑测试条件

输出第3~5行文本:

  1. [[email protected] ~]# awk -F: ‘NR>=3&&NR<=5{print}‘ passwd.txt
  2. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  3. adm:x:3:4:adm:/var/adm:/sbin/nologin
  4. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

严谨一点可以写成:

  1. [[email protected] ~]# awk -F: ‘(NR>=3)&&(NR<=5){print}‘ passwd.txt
  2. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  3. adm:x:3:4:adm:/var/adm:/sbin/nologin
  4. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

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

  1. [[email protected] ~]# awk -F: ‘NR==3||NR==5{print}‘ passwd.txt
  2. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  3. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

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

  1. [[email protected] ~]# awk -F: ‘$7!~/nologin$/||$1~/^[ad]/{print}‘ passwd.txt
  2. root:x:0:0:root:/root:/bin/bash
  3. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  4. adm:x:3:4:adm:/var/adm:/sbin/nologin
  5. sync:x:5:0:sync:/sbin:/bin/sync
  6. shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

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

  1. [[email protected] ~]# awk -F: ‘$3<3||$3%2==0{print}‘ passwd.txt
  2. root:x:0:0:root:/root:/bin/bash
  3. bin:x:1:1:bin:/bin:/sbin/nologin
  4. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  5. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  6. shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

4)数学运算

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

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

  1. [[email protected] ~]# awk -F: ‘BEGIN{x=0}
  2. {x+=NF} END{print "Total "x" fields."}‘ passwd.txt
  3. Total 49 fields.

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

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

  1. [[email protected] ~]# awk -F: ‘$3>=501&&$3<=505{print}‘ /etc/passwd
  2. hunter:x:501:501::/home/hunter:/bin/bash
  3. vina:x:502:502::/home/vina:/bin/bash
  4. kdev:x:503:503::/home/kdev:/bin/bash
  5. zengye:x:504:504::/home/zengye:/bin/bash
  6. stu01:x:505:1201::/tech/nsdhome/stu01:/bin/bash

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

  1. [[email protected] ~]# awk -F: ‘/^127|^192/{print}‘ /etc/hosts
  2. 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
  3. 192.168.4.5 svr5.tarena.com svr5

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

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

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

  1. [[email protected] ~]# seq 100
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 7
  9. 8
  10. 9
  11. 10
  12. .. ..

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

  1. [[email protected] ~]# seq 100 | awk ‘NR%7==0||NR~/7/{print}‘
  2. 7
  3. 14
  4. 17
  5. 21
  6. 27
  7. 28
  8. 35
  9. 37
  10. 42
  11. 47
  12. .. ..

或者:

  1. [[email protected] ~]# seq 100 | awk ‘$0%7==0||$0~/7/{print}‘
  2. 7
  3. 14
  4. 17
  5. 21
  6. 27
  7. 28
  8. 35
  9. 37
  10. 42
  11. 47
  12. .. ..

3 案例3:awk综合脚本应用

3.1 问题

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

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

图-2

3.2 步骤

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

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

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

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

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

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

  1. [[email protected] ~]# cat getupwd.sh                     //确认原脚本内容
  2. #/bin/bash
  3. > /tmp/getupwd.log                 ## 创建空文件
  4. sed -n ‘/:/bin/bash$/w /tmp/urec.tmp‘ /etc/passwd     ## 提取符合条件的账号记录
  5. UNUM=$(egrep -c ‘.‘ /tmp/urec.tmp)                 ## 取得记录个数
  6. while [ ${i:=1} -le $UNUM ]                     ## 从第1行开始,遍历账号记录
  7. do
  8. UREC=$(sed -n "${i}p" /tmp/urec.tmp)             ## 取指定行数的记录
  9. NAME=${UREC%%:*}                         ## 截取用户名(记录去尾)
  10. PREC=$(sed -n "/^$NAME:/p" /etc/shadow)         ## 查找与用户名对应的密码记录
  11. PASS=${PREC#*:}                         ## 掐头
  12. PASS=${PASS%%:*}                     ## 去尾,只留下密码记录
  13. echo "$NAME --> $PASS" >> /tmp/getupwd.log         ## 保存结果
  14. let i++                         ## 自增1,转下一次循环
  15. done
  16. /bin/rm -rf /tmp/urec.tmp                 ## 删除临时文件
  17. echo "用户分析完毕,请查阅文件 /tmp/getupwd.log"         ## 完成后提示
  18. [[email protected] ~]# cp getupwd.sh getupwd-awk.sh         //复制为新脚本文件

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

  1. [[email protected] ~]# vim getupwd-awk.sh
  2. #/bin/bash
  3. ## 创建空文件
  4. > /tmp/getupwd.log
  5. ## 提取用户名列表
  6. awk -F: ‘/:/bin/bash$/{print $1}‘ /etc/passwd > /tmp/users.tmp
  7. ## 通过for循环遍历用户名、查询密码记录,保存结果
  8. for NAME in $(cat /tmp/users.tmp)
  9. do
  10. grep "^$NAME:" /etc/shadow | awk -F: ‘{print $1" --> "$2 |
  11. "cat >> /tmp/getupwd.log"}‘ /etc/shadow
  12. done
  13. echo "用户分析完毕,请查阅文件 /tmp/getupwd.log" ## 完成后提示
  14. [[email protected] ~]# chmod +x getupwd-awk.sh

步骤三:验证、测试脚本

  1. [[email protected] ~]# ./getupwd-awk.sh
  2. 用户分析完毕,请查阅文件 /tmp/getupwd.log
  3. [[email protected] ~]# head -5 /tmp/getupwd.log
  4. root --> $6$IWgMYmRACwdbfwBo$dr8Yn983nswiJVw0dTMjzbDvSLeCd1GMYjbvsDiFEkL8jnXOLcocBQypOCr4C6BRxNowIxjh6U2qeFU0u1LST/
  5. zengye --> $6$Qb37LOdzRl5995PI$L0zTOgnhGz8ihWkW81J.5XhPp/l7x2./Me2ag0S8tRndCBL9nIjHIKkUKulHxJ6TXyHYmffbVgUT6pbSwf8O71
  6. clamav --> !!
  7. mysql --> !!
  8. abc --> !!
  9. .. ..

4 案例4:awk流程控制

4.1 问题

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

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

4.2 步骤

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

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

1)单分支

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

  1. [[email protected] ~]# awk -F: ‘BEGIN{i=0}{if($3<=500){i++}}END{print i}‘ /etc/passwd
  2. 39

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

  1. [[email protected] ~]# awk -F: ‘BEGIN{i=0}{if($3>500){i++}}END{print i}‘ /etc/passwd
  2. 28

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

  1. [[email protected] ~]# awk -F: ‘BEGIN{i=0}{if($7~/bash$/){i++}}END{print i}‘
  2. /etc/passwd
  3. 29

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

  1. [[email protected] ~]# awk -F: ‘BEGIN{i=0}{if($7!~/bash$/){i++}}END{print i}‘
  2. /etc/passwd
  3. 38

2)双分支

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

  1. [[email protected] ~]# awk -F: ‘BEGIN{i=0;j=0}{if($3<=500){i++}else{j++}}END{print i,j}‘ /etc/passwd
  2. 39 28

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

  1. [[email protected] ~]# awk -F: ‘BEGIN{i=0;j=0}{if($7~/bash$/){i++}else{j++}}
  2. END{print i,j}‘ /etc/passwd
  3. 29 38

3)多分支

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

  1. [[email protected] ~]# awk -F: ‘BEGIN{i=0;j=0;k=0}{if($7~/bash$/){i++}
  2. else if($7~/nologin$/){j++}else{k++}}END{print i,j,k}‘ /etc/passwd
  3. 29 33 5

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

1)while循环

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

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

  1. [[email protected] ~]# awk -F [:/]
  2. ‘BEGIN{j=0}
  3. {i=1}{while(i<=NF){if($i~/root/){j++};i++}}
  4. END{print j}‘ /etc/passwd
  5. 4

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

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

  1. [[email protected] ~]# echo $(cat /etc/passwd) | awk -F "root" ‘{print NF-1}‘
  2. 4

5 案例5:awk扩展应用

5.1 问题

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

  • 分析Web日志的访问量排名,要求获得客户机的地址、访问次数,并且按照访问次数排名

5.2 方案

1)awk统计Web访问排名

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

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

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

5.3 步骤

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

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

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

1)提取IP地址及访问量

  1. [[email protected] ~]# awk ‘{ip[$1]++} END{for(i in ip) {print i,ip[i]}}‘ /var/log/httpd/access_log
  2. 127.0.0.1 4
  3. 192.168.4.5 17
  4. 192.168.4.110 13
  5. .. ..

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

  1. [[email protected] ~]# awk ‘{ip[$1]++} END{for(i in ip) {print i,ip[i]}}‘ /var/log/httpd/access_log | sort -nr -k 2
  2. 192.168.4.5 17
  3. 192.168.4.110 13
  4. 127.0.0.1 4
  5. .. ..

awk的数组的应用

1、tcp的连接状态##netstat-ant|awk-F""‘NR>2++TCP[$NF]ENDfor(iinTCP)printi,TCP[i]‘LISTEN4ESTABLISHED1##netstat-ant|awk‘/^tcp/++TCP[$NF]ENDfor(iinTCP)printi,TCP[i]‘LISTEN4ESTABLISHED12、awk 查看详情

shell脚本——awk详细介绍(包含应用案例)(代码片段)

三剑客awk详解awk概述awk处理文本方式awk工作原理awk语法汇总示例内部变量格式化输出模式(正则表达)和动作概念字符串比较数值比较目的关系运算符算术运算多条件运算awk脚本编程变量条件判断循环数组awk编程案例awk... 查看详情

awk入门教程及应用场景

基本用法awk是一个强大的文本分析工具,简单来说awk就是把文件逐行读入,(空格,制表符)为默认分隔符将每行切片,切开的部分再进行各种分析处理awk命令格式如下awk[-Ffield-separator]commandsinput-file(s)[-F分隔符]是可选的,因为a... 查看详情

linux三剑客awk的应用对比案例详解

   awk的格式一awk  参数  ‘条件’(单引号) 文件路径a.参数我们一般用-F “[]” (双引号) 指定分隔符b.条件 为BEGIN模块 + 模式条件 +END模块b1.BEGIN模块在执行awk读取文件之... 查看详情

shell编程之awk(数据筛选与处理)(代码片段)

...wk(数据筛选与处理)awk命令介绍awk语法awk的基本应用awk对字段(列)的提取awk对记录(行)的提取awk程序的优先级awk高级应用-F命令选项awk定义变量(-v命令)awk定义数组awk运算awk比较预算:>... 查看详情

十七.正则以及grep,sed,awk的简单应用

一.正则表达式://grep,sed,awk都能解释正则表达式正则表达式:把一些特殊符号组合到一起描述字符和字符串的方法。^以什么开头grep‘^root‘/etc/passwd$以什么结尾如能登入系统的所有用grep‘bash$’/etc/passwd.任意一个字符grep‘^b.n... 查看详情

grep,sed,awk与简单正则表达式应用(代码片段)

grep,sed,awk与简单正则表达式应用这里使用的测试文件是linux/etc/passwd文件,最好是复制一份进行练习,方式对文件内容造成损坏。感觉还是要多练习才能很好的使用,习题这里就不贴了,网上一找一大把。grep:  -o用作计算... 查看详情

通过grep,awk,sed的简单应用获取网卡信息。

本文主要通过shell命令来实现获取网卡信息。通过cmd_shell函数可以将运行命令后的输出返回。  intcmd_shell(char*shellcmd,char*outbuffer,intsize){FILE*stream;charbuffer[size];memset(buffer,0,sizeof(buffer));stream=popen(shellcmd,"r");if(stream 查看详情

shell脚本应用正则表达式grep,sed,awk,的应用

 准备测试文件从test.txt文件中查找出特定字符“the”所在的位置查找不包含“the”字符的行同时查找到“shirt”与“short”这两个字符串查找包含重复单个字符“oo”查找“oo“前面不是”w“的字符串查找“oo”前面不存在小写字... 查看详情

使用 AWK 解析命名参数值

...:我正在尝试提出一个脚本/别名,它可以快速为我提供应用程序运行的进程列表。应用程序用于启动进程的参数是命名参数,而不是位置我需要提取-u、-s和-svn的参数值$ps-ef|greppmdtm|grep-vgrepinfa_adm24581311460Oct24?00 查看详情

将awk模式应用于具有相同名称的所有文件,将每个文件输出到新文件(代码片段)

...递归方式在目录中查找具有相同名称的所有文件,对它们应用awk模式,然后输出到每个文件都存在该文件的新更新版本的目录。我认为使用for循环比使用xargs更好,但我不知道如何使这个工作...forfin$(find。-nameFILENAME.txt);doawk-F... 查看详情

awk用法练习

...少个变量需要赋值,就需要多少个-v选项。与之等价的:应用于脚本中:#!/bin/bashsort-nfilename|awk-F‘:‘‘{print$1}‘|uniq>id.txtforidincatid.txt;do 查看详情

sed 和 awk 有啥区别? [关闭]

...【问题描述】:awk有什么区别和sed吗?最好使用什么样的应用程序sed和awk工具的案例?【问题讨论】:有关unix.stackexchange的相关QA:Isthereabasictutorialforgrep,aw 查看详情

正则介绍awk

...到的。awk工具其实是很复杂的,有专门的书籍来介绍它的应用,不过我认为学那么复杂没有必要,只要能处理日常管理工作中的问题即可。同样的,做一下准备工作,见下图,先操作awk最简单的功能,指定分隔符-F,来查看一下... 查看详情

awk(代码片段)

...印多列时用,逗号分隔)awk–F”:”‘print3,$4’/etc/passwd应用:IP地址的获取。[email protected]:/home/whatispython/workspace/sh 查看详情

linux系统常用指令grepsed和awk(代码片段)

...论2grep指令2sed指令2.1sed特点及格式2.2sed执行过程2.3sed核心应用3awk指令3.1awk执行过程3.2awk之行与列3.3awk之模式匹配3.4awk数组3.5awk循环与判断1概论命令特点场景grep过滤grep命令过滤速度是最快的sed替换,修改文件内容,取行... 查看详情

awk详解

...w.ruanyifeng.com/blog/2018/11/awk.html ??awk是处理文本文件的一个应用程序,几乎所有Linux系统都自带这个程序。 它依次处理文件的每一行,并读取里面的每一个字段。对于日志、CSV那样的每行格式相同的文本文件,awk可能是最方便的工... 查看详情

shell脚本之awk工具的使用

...的情况下实现相当复杂的文本操作,被我们运维人员广泛应用于shell脚本,完成各中自动化配置任务。awk可以直接处理目标文件,也可以和sed命令一样通过“-f”选项读取脚本对目标文件进行处理。awk的语法格式如下:sed命令常... 查看详情