Linux文本处理三剑客之awk详解

一、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具有了三个值,01122,将数组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最大字符串长度,或小数点右面的位数
%cASCII字符
%d整型
%e科学计数法
%f浮点型
%gawk决定哪种浮点数转换e或者f,自动选择合适的表示法
%o以八进制表示的整数
%s字符串
%x以十六进制表示的整数
\n输出新的一行,换行输出
\r回车
\ttab键

说明:
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 87 18:56 anaconda-ks.cfg
-rw-r--r--. 1 root  root         10 821 20:52 a.txt
-rw-r--r--. 1 harry harry        19 822 10:46 b.txt
-rw-r--r--. 1 root  root          0 820 16:30 ceshi.txt
-rw-r--r--. 1 root  root       2427 816 14:05 dajihe.zip
-rw-r--r--. 1 root  root  196075027 814 17:46 Golden.apk
drwxr-xr-x. 2 root  root         35 816 10:53 harry
-rw-r--r--. 1 root  root       1188 816 11:49 harry.zip
-rw-r--r--. 1 root  root  166343742 816 11:52 jihe.zip
-rwxr-xr-x. 1 root  root       1562 814 17:47 time.sh
-rwxr-xr-x. 1 root  root        190 820 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 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值