一、awk工具介绍
awk是一个强大的文本分析工具,跟sed一样,是面向行的处理工具,不过awk也可以对每行进行切片处理,也就是所谓的列,在对数据进行分析时功能尤为强大。
二、awk的基本使用
格式:awk [选项] ‘[条件]{指令}’ filename
其中,print是awk工具最常用的编辑命令,可以使用分号分隔。
awk过滤数据时支持仅打印文件的某一列,如第2列、第3列等。
处理文件时,若没有指定分隔符,则默认将空格、制表符等作为分隔符。
awk同样也支持正则
过滤文件内容:
源文件内容:
[root@redhat ~]#cat a.txt
wo shi redhat7
ni shi centos6
打印文件按的第1列和第3列:
[root@redhat ~]#awk '{print $1,$3}' a.txt
wo redhat7
ni centos6
结合管道过滤命令输出:
查看磁盘剩余空间:
[root@redhat ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/rhel-root 17G 1.5G 16G 9% /
devtmpfs 901M 0 901M 0% /dev
tmpfs 912M 0 912M 0% /dev/shm
tmpfs 912M 8.4M 904M 1% /run
tmpfs 912M 0 912M 0% /sys/fs/cgroup
/dev/sda1 1014M 143M 872M 15% /boot
tmpfs 183M 0 183M 0% /run/user/0
打印磁盘剩余的总空间:
[root@redhat ~]#df -h | sed -n '2p' | awk '{print $4}'
16G
或使用正则匹配:
[root@redhat ~]# df -h | head -2 | tail -1 | awk '/\/$/{print $4}'
16G
玩法很多,可以用自己学过的知识多练习
使用-F可以指定分隔符:
输出/etc/passwd文件中以冒号分隔的第1、第7个字段,操作如下:
#print打印不同字段之间以逗号隔开,如果不使用逗号隔开打印出来的字段之间是连接在一起的,没有空格
[root@redhat ~]# awk -F: '{print $1,$7}' /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
systemd-network /sbin/nologin
dbus /sbin/nologin
polkitd /sbin/nologin
postfix /sbin/nologin
chrony /sbin/nologin
sshd /sbin/nologin
awk还可以识别多种单个字符,比如以":“或”/“分隔,输出第1和第10个字段:
注意:如果以”:“或”/“分隔作为分隔符,则文件中每一行遇到连续的”:“和”/",则它们之间的内容为空,所以在输出的时候可能会有输出的列为空的情况,看下面,拿出/etc/passwd中sshd开头的这一行举个列子:
sshd : x : 74 : 74 : Privilege-separated SSH: / var / empty / sshd : / sbin / nologin
1 2 3 4 5 6 7 8 9 10 11 12
#可以看到第10列正好为空
[root@redhat ~]# awk -F[:/] '{print $1,$10}' /etc/passwd
root bash
bin nologin
daemon nologin
adm sbin
lp
sync sync
shutdown shutdown
halt halt
mail
operator nologin
games sbin
ftp sbin
nobody nologin
systemd-network nologin
dbus nologin
polkitd nologin
postfix
chrony
sshd
awk常用的内置变量
变量 | 作用 |
---|---|
$0 | 输出文本当前行的全部内容 |
$1 | 输出文本的第一列 |
$2 | 输出文本的第二列 |
$3 | 输出文本的第三列,以此类推 |
NR | 输出文件当前行的所有行号 |
NF | 输出文件当前行的列数(有几列) |
awk应用实例:
1.输出每次处理行的行号,以及当前行以":"为分隔符的字段个数(有几列):
[root@redhat ~]# awk -F: '{print NR,NF}' /etc/passwd
1 7
2 7
3 7
4 7
5 7
... ...
2.awk的print指令不仅可以打印变量,也可以打印常量:
[root@redhat ~]# awk -F: '{print $1"的解释:"$7}' /etc/passwd
root的解释:/bin/bash
bin的解释:/sbin/nologin
daemon的解释:/sbin/nologin
adm的解释:/sbin/nologin
lp的解释:/sbin/nologin
sync的解释:/bin/sync
shutdown的解释:/sbin/shutdown
halt的解释:/sbin/halt
mail的解释:/sbin/nologin
operator的解释:/sbin/nologin
games的解释:/sbin/nologin
ftp的解释:/sbin/nologin
nobody的解释:/sbin/nologin
systemd-network的解释:/sbin/nologin
dbus的解释:/sbin/nologin
polkitd的解释:/sbin/nologin
postfix的解释:/sbin/nologin
chrony的解释:/sbin/nologin
sshd的解释:/sbin/nologin
查看本机有哪些网卡,现在使用的是哪个网卡:
[root@redhat ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.12 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::20c:29ff:fe23:9382 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:23:93:82 txqueuelen 1000 (Ethernet)
RX packets 101062 bytes 10218104 (9.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1525 bytes 182521 (178.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
3.提取本机的IP地址:
[root@redhat ~]# ifconfig ens33 | sed -n '2p' | awk '{print $2}'
192.168.0.12
4.过滤出接收数据的流量:
RX为接收数据的流量,TX为发送数据的流量。packets以数据包的数量为单位,bytes以字节为单位。
[root@redhat ~]# ifconfig ens33 | awk '/RX p/{print $5}'
11108404
5.过滤出发送数据的流量:
[root@redhat ~]# ifconfig ens33 | awk '/TX p/{print $5}'
221119
三、awk处理的时机
awk会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行之后做一些总结性质的工作。在命令格式上分别体现如下:
awk [选项] ‘[条件]{指令}’ filename
awk [选项] ’ BEGIN{指令} {指令} END{指令}’ filename
BEGIN{ } 行前处理,读取文件内容前执行,指令执行1次
{ } 逐行处理,读取文件过程中执行,指令执行n次
END{ } 行后处理,读取文件结束后执行,指令执行1次
只做预处理的时候,可以没有操作文件,比如:
[root@redhat ~]# awk 'BEGIN{A=12;print A*3}'
36
[root@redhat ~]# awk 'BEGIN{print B+3}' //B可以不定义,直接用,默认值为0
3
[root@redhat ~]# awk 'BEGIN{print 2.5+3.8}'
6.3
举个例子(统计系统中使用bash作为登录Shell的用户总个数):
a.预处理时赋值变量x=0
b.然后逐行读入/etc/passwd文件,如果发现登录Shell是/bin/bash则x加1
c.全部处理完毕后,输出x的值即可。相关操作及结果如下:
[root@redhat ~]# awk 'BEGIN{x=0}/bash$/{x++} END{print x}' /etc/passwd
2
格式化输出/etc/passwd文件(awk同样支持制表符\t和换行符\n):
要求: 格式化输出passwd文件内容时,要求第一行为列表标题,中间打印用户的名称、UID、家目录信息,最后一行提示一共已处理文本的总行数:
[root@redhat ~]# awk -F: 'BEGIN{print "User\tUID\tHome"}{print $1"\t"$3"\t"$6} END{print "Total",NR,"line."}' /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
shutdown 6 /sbin
halt 7 /sbin
mail 8 /var/spool/mail
operator 11 /root
games 12 /usr/games
ftp 14 /var/ftp
nobody 99 /
systemd-network 192 /
dbus 81 /
polkitd 999 /
postfix 89 /var/spool/postfix
chrony 998 /var/lib/chrony
sshd 74 /var/empty/sshd
wuyoupin 1000 /home/wuyoupin
Total 20 line.
四、awk处理条件
使用正则设置条件:
1.输出/etc/passwd文件中以bash结尾的完整记录:
[root@redhat ~]# awk -F: '/bash$/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
2.输出/etc/passwd文件中包含root的行数据:
[root@redhat ~]# awk -F: '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
3.输出/etc/passwd文件中root或adm账户的用户名和UID信息:
[root@redhat ~]# awk -F: '/^(root|adm)/{print $1,$3}' /etc/passwd
root 0
adm 3
4.输出/etc/passwd文件中账户名称包含root的基本信息(第1列包含root):
[root@redhat ~]# awk -F: '$1~/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
5.输出/etc/passwd文件中登陆shell不以nologin结尾的用户名、登陆shell信息:
#可以对第7个字段做反向匹配
[root@redhat ~]# awk -F: '$7!~/nologin$/{print $1,$7}' /etc/passwd
root /bin/bash
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
使用数值/字符串比较设置条件:
比较符号 | 作用 |
---|---|
== | 等于 |
!= | 不等于 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
1.输出/etc/passwd文件的第3行的用户记录:
[root@redhat ~]# awk -F: 'NR==3{print}' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
2.输出/etc/passwd文件中账户UID大于等于900的账户名称和UID:
[root@redhat ~]# awk -F: '$3>=900{print $1,$3}' /etc/passwd
polkitd 999
chrony 998
3.输出/etc/passwd文件中账户UID小于10的账户名称和UID信息:
[root@redhat ~]# awk -F: '$3<10{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
4.输出/etc/passwd文件中用户名为root的行:
[root@redhat ~]# awk -F: '$1=="root"{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
逻辑测试条件:
1.输出/etc/passwd文件中用户账户UID大于10并且小于20的账户信息:
[root@redhat ~]# awk -F: '$3>10 && $3<20' /etc/passwd
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
2.输出/etc/passwd文件中账户UID大于900或者账户UID小于10的账户信息:
[root@redhat ~]# awk -F: '$3>900 || $3<10' /etc/passwd
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
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
数学运算
[root@redhat ~]# awk 'BEGIN{x++;print x}'
1
[root@redhat ~]# awk 'BEGIN{x=8;print x+=2}'
10
[root@redhat ~]# awk 'BEGIN{x=8;x--;print x}'
7
[root@redhat ~]# awk 'BEGIN{print 2+3}'
5
[root@redhat ~]# awk 'BEGIN{print 2*3}'
6
[root@redhat ~]# awk 'BEGIN{ print 23%8}' //求23除以8的余数
7
[root@redhat ~]# seq 20 | awk '$1%3==0' //求20以内30的倍数
3
6
9
12
15
18
练习:
1.列出/etc/passwd文件中UID间于1~900的用户详细信息:
[root@redhat ~]# awk -F: '$3>=1 && $3<=900' /etc/passwd
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
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
2.输出/etc/hosts映射文件内以127或者:开头的记录:
[root@redhat ~]# awk '/^(127|:)/' /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
3.列出30以内整数中7的倍数或者含7的数:
[root@redhat ~]# seq 30 | awk '$1%7==0||$1~/7/'
7
14
17
21
27
28
写一个简单的脚本练习一下
编写脚本的任务要求如下:
分析出使用bash作登录Shell的本地用户
列出这些用户的shadow密码记录
按每行“用户名 – 密码记录”保存结果
[root@redhat ~]#vim get_user_password.sh
#!/bin/bash
user=$(awk -F: '/bash$/{parint $1}' /etc/passwd)
for i in ${user}
do
grep ${i} /etc/shadow | awk -F: '{print $1,"-->",$2}'
done
五、awk流程控制
1.awk过滤中if分支结构
a.单分支
统计/etc/passwd文件中UID小于或等于10的用户个数:
[root@redhat ~]# awk -F: '{if($3<=10){i++}}END{print i}' /etc/passwd
9
统计/etc/passwd文件中UID大于850的用户个数:
[root@redhat ~]# awk -F: '{if($3>=850){i++}}END{print i}' /etc/passwd
3
统计/etc/passwd文件中登录Shell是“/bin/bash”的用户个数:
[root@redhat ~]# awk -F: '{if($7=="/bin/bash"){i++}}END{print i}' /etc/passwd
2
或者
[root@redhat ~]# awk -F: '{if($7~/bash$/){i++}}END{print i}' /etc/passwd
2
b.双分支
分别统计/etc/passwd文件中UID小于或等于500、UID大于500的用户个数:
[root@redhat ~]# awk -F: '{if($3<500){i++}else{j++}}END{print "UID小于500的账户的个数:"i"\n""UID大于500的账户的个数:"j}' /etc/passwd
UID小于500的账户的个数:17
UID大于500的账户的个数:3
#为了显示效果好看一点,我这里给输出加上了换行符,换行输出
六、awk数组
1.数组的语法格式:
数组是一个可以存储多个值的变量,具体使用的格式如下:
定义数组的格式:数组名[下标]=元素值
调用数组的格式:数组名[下标]
遍历数组的用法:for(变量 in 数组名){print 数组名[变量]}。
[root@redhat ~]# awk 'BEGIN{a[0]=11;a[1]=88;print a[1],a[0]}'
88 11
#参考解释:定义数组a[0]=11,a[1]=88,输出a[0]与a[1]的值
[root@redhat ~]# awk 'BEGIN{a++;print a}'
1
[root@redhat ~]# awk 'BEGIN{a0++;print a0}'
1
[root@redhat ~]# awk 'BEGIN{a[0]++;print a[0]}'
1
[root@redhat ~]# awk 'BEGIN{a[0]=0;a[1]=11;a[2]=22; for(i in a){print i,a[i]}}'
0 0
1 11
2 22
参考解释:定义数组a,a[0]=0,a[1]=11,a[2]=22,这时候数组a具有了三个值,0、11、22,将数组a作为值列表赋值给变量i做for循环,每一次循环都输出i的值跟a[i]的值,第一次循环i=0,a[i]=a[0]=0,第二次循环i=1,a[i]=a[1]=11,第三次循环i=2,a[i]=a[2]=22,所以最后输出的结果如上
七、awk格式化输出
注意:awk格式化输出的打印命令为printf,printf()函数是格式化输出函数,一般用于向标准输出设备按规定格式输出信息。
printf()函数的调用格式为:printf(" “,);
其中格式化字符串包括两部分内容:逗号前面的内容是格式化规定字符,以”%"开始,后面跟着的是规定字符,用来确定输出格式,逗号后面的部分是正常字符,这些字符是按原样输出的。
- | 左对齐 |
---|---|
Width | 域的步长,用0表示0步长 |
.prec | 最大字符串长度,或小数点右面的位数 |
%c | ASCII字符 |
%d | 整型 |
%e | 科学计数法 |
%f | 浮点型 |
%g | awk决定哪种浮点数转换e或者f,自动选择合适的表示法 |
%o | 以八进制表示的整数 |
%s | 字符串 |
%x | 以十六进制表示的整数 |
\n | 输出新的一行,换行输出 |
\r | 回车 |
\t | tab键 |
说明:
1.可以在"%"和字符之间插入数字表示最大长度。
例如:
%5s表示输出5位字符串,不够5位右对齐由空格补全,想要左对齐则可以用%-5s表示,左对齐,不够5位字符串则由空格补全
%5d 表示输出5位整型数, 不够5位右对齐。
%8.2f 表示输出场宽为8的浮点数, 其中小数位为2, 整数位为5,小数点占一位, 不够8位右对齐。
如果字符串的长度、或整型数位数超过说明的场宽, 将按其实际长度输出.但对浮点数, 若整数部分位数超过了说明的整数位宽度, 将按实际整数位输出;若小数部分位数超过了说明的小数位宽度, 则按说明的宽度以四舍五入输出.
若想在输出值前加一些0, 就应在场宽项前加个0。
例如: %05s 表示在输出一个小于5位的字符串时, 将在前面补0使其总宽度为5位。
如果用浮点数表示字符或整型量的输出格式, 小数点后的数字代表最大宽度,小数点前的数字代表最小宽度。
例如: %6.8s 表示显示一个长度大于或者等于6且小于或者等于9的字符串。若大于9, 则第9个字符以后的内容将被删除。
2.可以在"%"和格式化输出字符之间加小写字母l,表示输出的是长型数
例如:
%ld表示输出的是长型数整数
%lf表示输出的是double浮点数
3.可以控制输出左对齐或右对齐, 即在"%“和字母之间加入一个”-" 号可说明输出为左对齐, 否则为右对齐。
例如:
%-5d 表示输出5位整数左对齐
%-5s 表示输出5个字符左对齐
实例:
1.输出df -Th的命令结果的第2列和第5列,其中第2列是输出12个字符串为格式,不够的空格补足,右对齐,第5列是输出15个字符串为格式,不够空格补足,右对齐。
[root@redhat ~]# df -Th | awk '{printf "%12s %15s\n",$2,$5}'
类型 可用
xfs 16G
devtmpfs 901M
tmpfs 912M
tmpfs 904M
tmpfs 912M
xfs 872M
tmpfs 183M
2.输出df -Th的命令结果的第2列和第5列,其中第2列是输出12个字符串为格式,不够的空格补足,右对齐,第5列是输出15个字符串为格式,不够空格补足,左对齐。
[root@redhat ~]# df -Th | awk '{printf "%-12s %-15s\n",$2,$5}'
类型 可用
xfs 16G
devtmpfs 901M
tmpfs 912M
tmpfs 904M
tmpfs 912M
xfs 872M
tmpfs 183M
3.整数换行输出第1列:
[root@redhat ~]# echo "3.5 2.85" | awk '{printf "%d\n",$1}'
3
[root@redhat ~]# echo "1.8 2.85" | awk '{printf "%d\t%05d\n",$1,$2}'
1 00002 //整数位不够在整数前面用0补齐
4.浮点换行输出第1列:
[root@redhat ~]# echo "1.3 2.85" | awk '{printf "%f\n",$1}'
1.300000
[root@redhat ~]# echo "1.32 2.85" | awk '{printf "%f\n",$1}'
1.320000
四舍五入输出整数:
[root@redhat ~]# echo 3.3 | awk '{printf "%.f\n",$1}'
3 //舍
[root@redhat ~]# echo 3.5 | awk '{printf "%.f\n",$1}'
4 //入
以3位长度、1位小数,"."占一位,浮点换行输出第2列,小数位超过需要四舍五入:
[root@redhat ~]# echo "1.7 2.853" | awk '{printf "%3.1f\n",$2}'
2.9 //0.853小数点后面的数字四舍五入变为0.9
八、awk的扩展应用
1.统计Web访问量排名
在分析Web日志文件时,每条访问记录的第一列就是客户机的IP地址,其中会有很多重复的IP地址。因此只用awk提取出这一列是不够的,还需要统计重复记录的数量并且进行排序。
通过awk提取信息时,利用IP地址作为数组下标,每遇到一个重复值就将此数组元素递增1,最终就获得了这个IP地址出现的次数。
针对文本排序输出可以采用sort命令,相关的常见选项为-r、-n、-k。其中-n表示按数字顺序升序排列,而-r表示反序,-k可以指定按第几个字段来排序。
cat /var/log/httpd/access_log | awk '{IP[$1]++}END {for (i in IP){ if (IP[i]>=3) {print IP[i],i}}}' |uniq | sort -nr
9 192.168.0.12
8 127.0.0.1
#这个例子加上了if判断,连接数大于或者等于3才会执行
#显示的结果前面的数字表示的是后面的ip的连接次数
2.按格式输出每一行的倒数第二列,最后一列,总列数:
a.输出文件每一行的倒数第二列:
[root@redhat ~]#cat a.txt | awk '{print $(NF-1)}'
b.输出文件每一行的最后一列:
[root@redhat ~]#cat a.txt | awk '{print $(NF)}'
c…输出文件每一行的列数:
[root@redhat ~]#cat a.txt | awk '{print NF}'
3.awk实现求和、平均值,最大值和最小值的计算操作
原文件内容:
[root@redhat ~]# cat a.txt
12
14
15
1.求和
[root@redhat ~]# cat a.txt | awk '{sum+=$1} END {print "Sum = ", sum}'
Sum = 41
2.求平均值
[root@redhat ~]# cat a.txt | awk '{sum+=$1} END {print "Average = ", sum/NR}'
Average = 13.6667
3.求最大值
[root@redhat ~]# cat a.txt | awk 'BEGIN {max = 0} {if ($1>max) max=$1 fi} END {print "Max=", max}'
Max= 15
4.求最小值
[root@redhat ~]# cat a.txt | awk 'BEGIN {min = 1999999} {if ($1<min) min=$1 fi} END {print "Min=", min}'
Min= 12
5.求100以内的整数相加的和,包括100
[root@redhat ~]# seq 100 | awk '{sum+=$1} END {print "Sum = ", sum}'
Sum = 5050
6.求100以内的整数相加的平均数,包括100
[root@redhat ~]# seq 100 | awk '{sum+=$1} END {print "Average = ", sum/NR}'
Average = 50.5
7.计算/root/目录下普通文件的大小,使用KB作为单位:
[root@redhat ~]# ll | awk 'BEGIN{sum=0}!/^d/{sum+=$5}END{print "total size is:"sum/1024"KB"}'
total size is:353931KB
8.统计/root/目录下不同用户的普通文件的个数:
先查看一下/root/目录下的文件的情况,方便等下确认结果:
[root@redhat ~]# ll
总用量 353956
-rw-------. 1 root root 1621 8月 7 18:56 anaconda-ks.cfg
-rw-r--r--. 1 root root 10 8月 21 20:52 a.txt
-rw-r--r--. 1 harry harry 19 8月 22 10:46 b.txt
-rw-r--r--. 1 root root 0 8月 20 16:30 ceshi.txt
-rw-r--r--. 1 root root 2427 8月 16 14:05 dajihe.zip
-rw-r--r--. 1 root root 196075027 8月 14 17:46 Golden.apk
drwxr-xr-x. 2 root root 35 8月 16 10:53 harry
-rw-r--r--. 1 root root 1188 8月 16 11:49 harry.zip
-rw-r--r--. 1 root root 166343742 8月 16 11:52 jihe.zip
-rwxr-xr-x. 1 root root 1562 8月 14 17:47 time.sh
-rwxr-xr-x. 1 root root 190 8月 20 20:36 vsftp.sh
统计:
[root@redhat ~]# ll | awk 'BEGIN{print "用户名","文件个数"}{NR!=1 && !/^d/sum[$3]++}END{for (i in sum) printf "%-8s %-8s\n",i,sum[i]}'
用户名 文件个数
harry 1
root 10
9.来个大家伙试试,输出成绩表:
原文件内容:
[root@redhat ~]# cat chengjibiao.txt
harry 68 68 65 70
bobo 50 70 68 75
tom 45 75 75 80
mike 1 85 90 96
jack 5 80 85 90
输出成绩表:
awk 'BEGIN{math=0;eng=0;com=0;printf "Lineno. Name No. Math English Computer Total\n";printf "------------------------------------------------------------\n"}{math+=$3; eng+=$4; com+=$5;printf "%-8s %-7s %-7s %-7s %-9s %-10s %-7s \n",NR,$1,$2,$3,$4,$5,$3+$4+$5} END{printf "------------------------------------------------------------\n";printf "%-24s %-7s %-9s %-20s \n","Total:",math,eng,com;printf "%-24s %-7s %-9s %-20s \n","Avg:",math/NR,eng/NR,com/NR}' chengjibiao.txt