linux常用命令-awk使用

awk的基本功能是查找匹配固定模式的行。当一行匹配其中的一个模式,那么awk就会对这一行执行这个模式后面的操作。按此流程去处理读取文件中的行,直到文件末尾。

调用有二种方式:

1.awk   -F"分隔符"  "command" filename

2.是将所有的awk命令插入一个单独文件,然后调用
  awk -f awk-script-file  filename

字段的引用
$字段操作符
$1代表第一列,$2代表第二列。。。n以此类推
$0代表整个输入记录

比较:

cut -d" "  -f1
sort -t" " -k1
awk -F" " '{print $1}'

先用awk和cut做截取,来进行几个比较

比较一:用cut和awk截取IP

ifconfig eth0 |grep Bcast |cut -d ":" -f2|cut -d" " -f1

ifconfig eth0 |grep Bcast |awk -F: '{print $2}'|awk  '{print $1}'

ifconfig eth0 |grep Bcast | awk -F" " '{print $2}'|awk -F":" '{print $2}'

--awk默认以N个空格为分隔符

比较二:
cut不能以多个字符为分隔符,而awk 可以
下面都是以ab为分隔符,截取第二列的做法,cut报错,awk成功

# echo 123ab456ab789 |cut -d"ab" -f2
cut: the delimiter must be a single character
Try `cut --help' for more information.
# echo 123ab456ab789 |awk -F"ab" '{print $2}'
456

比较三:

#打印所有列:    
awk '{print $0}' /etc/passwd
#打印第一列:
awk -F: '{print $1}' /etc/passwd
#打印第一,三列:  
awk -F: '{print $1"\thaha\t"$3}' /etc/passwd

# awk -F":" '{print $1" 的uid是 "$3}' /etc/passwd

--上面这条如果要用cut来实现,得写下面的脚本

#!/bin/bash

cat /etc/passwd | cut -d: -f1,3 |while read a
do
        head=`echo $a|cut -d: -f1`
        tail=`echo $a|cut -d: -f2`
        echo  "$head的uid是$tail"
done

# awk -F":" '{print $1"的uid是"$3",登录shell是"$7}' /etc/passwd

比较四:

# who |tail -1
root     pts/0        2013-08-25 10:11 (:0.0)
# who |tail -1 |awk -F":|)" '{print $3}' --以:或)为分隔符
0.0

# who |tail -1
root     pts/3        2014-08-14 09:46 (10.1.1.111)
who |tail -1 |awk -F[\(\)] '{print $2}'	--以(或)为分隔符,加转义符
10.1.1.111

awk -F"[:)]"   --以:或)为分隔符
awk -F"[:)]*" --以多个连续的:或多个连续的)为分隔符

[[email protected] ~]# echo "haha,hehe.heihei" |awk -F"[,.]" '{print $1}'
haha
[[email protected] ~]# echo "haha,hehe.heihei" |awk -F"[,.]" '{print $2}'
hehe
[[email protected] ~]# echo "haha,hehe.heihei" |awk -F"[,.]" '{print $3}'
heihei

--象下面这样的字符串,以点为分隔符可以做,但是点号太多,不好数.所以可以用正则表达式,以连续的多个点来为分隔符
# echo "haha,hehe.......................................heihei........." |awk -F"[.]*" '{print $2}'
heihei

==========================华丽的分割线======================================

$n    n不一定要用整数,也可以用变量值代替
echo a b c |awk 'BEGIN {one=1;two=2} {print $(one+two)}'

awk  -F:  'BEGIN {处理文件前执行的代码块} {处理文件过程中执行的代码块} END {处理文件后执行的代码块}'   filename

一般结构:

BEGIN{

}
{

}
END	{

}

把上面的结构可以与下面的一个基本循环结构做对比

sum=0
for i in `seq 100`
do
sum=$[$sum+$i]
done
echo sum

# cat /etc/fstab |wc -l
10
# awk -F: 'BEGIN {print "这是第一行"} {print "这是第二行"} {print "这是第三行"} {print "这是第四行"} END {print "这是最后一行"}'  /etc/fstab |wc -l
32

--这个打印了32行,第一行一次,最后一行一次,中间的三行打了十次;3*10+2=32,正好对应fstab的行数;也就是说中间的代码循环的次数等同于后面的文件的行数

比较下面这两句

awk -F: '{print "用户名\t\tUID"}{print $1"\t"$3}' /etc/passwd
awk -F: 'BEGIN{print "用户名\t\tUID"}{print $1"\t"$3}' /etc/passwd

--下面两种结果相同,都是把列转成行

# head -1 /etc/passwd |awk -F":" '{print $1"\n"$2"\n"$3"\n"$4"\n"$5"\n"$6"\n"$7}'
# head -1 /etc/passwd |awk -F":" '{print $1} {print $2} {print $3} {print $4} {print $5} {print $6}{print $7}'

# head -1 /etc/passwd |awk -F: 'BEGIN {print "*************************"} {print "*\t"$1"\t\t*"} {print "*\t"$2"\t\t*"} {print "*\t"$3"\t\t*"} {print "*\t"$4"\t\t*"} {print "*\t"$5"\t\t*"} {print "*\t"$6"\t\t*"} {print "*\t"$7"\t*"} END {print "*************************"}'
*************************
*       root            *
*       x               *
*       0               *
*       0               *
*       root            *
*       /root           *
*       /bin/bash       *
*************************



# head -1 /etc/passwd |awk -F: 'BEGIN {print "*************************"} {print "*\t"$1"\t\t*\n*\t"$2"\t\t*\n*\t"$3"\t\t*\n*\t"$4"\t\t*\n*\t"$5"\t\t*\n*\t"$6"\t\t*\n*\t"$7"\t*"} END {print "*************************"}'
*************************
*	root		*
*	x		*
*	0		*
*	0		*
*	root		*
*	/root		*
*	/bin/bash	*
*************************

===============================================================

awk可以用做小数(浮点数)的运算

echo $[1.23*2]	--错误做法
echo |awk '{print 1.23*2}'	--正确做法
echo 1.23*2 | bc	--正确做法

=====================================================================


把/etc/passwd的第一行,按照:分为7列,左右倒序排列

# head -1 /etc/passwd |cut -d":" -f7,6,5,4,3,2,1
root:x:0:0:root:/root:/bin/bash

用cut,列数反着写,还是没有倒序,所以应该写一个循环,然后使用echo -n去再排列出来

例:

换成awk来做

# head -1 /etc/passwd |awk -F: '{print $7":"$6":"$5":"$4":"$3":"$2":"$1}'
# head -1 /etc/passwd |awk -F: 'BEGIN {OFS=":"}{print $7,$6,$5,$4,$3,$2,$1}'

--OFS是一个内置的变量,表示定义输出的分隔符

--上面这可能会有一个问题,就是上面做的只有7列,如果我有700列,我不可能手动从$700写到$1吧;所以可以用awk的for循环来做.(后面有一个例子会讲到)

awk  内置变量

FS   代表输入的分隔符,等同于-F ;  OFS代表输出的分隔符
NF   代表字段数 因为NF是列数,所以$NF就是代表最后一个列
NR   代表当前处理第几行

awk关系操作符

==   等于
!=    不等于
>    大于
<    小于
>=   大于等于
<=   小于等于

awk逻辑操作符

&& 逻辑与   类似shell里的[ 条件1 -a  条件2 ]
|| 逻辑或 类似shell里的[ 条件1 -o  条件2 ] 
! 非

awk运算操作符

+ - * / %
^或**  幂   比如:2的三次方  2^3 或2**3   --shell里面求幂只能为2**3

练习:用netstat -ntl 截取所有开放监听的TCP协议端口号

# netstat -ntl |awk 'NR >2 {print $4}'|awk -F: '{print $NF}'

练习:用netstat -ntl 截取所有开放监听的TCP协议端口号(只要IPv4的监听所有的开放端口)

# netstat -ntl |awk 'NR >2 {print $4}' | grep ^0.0.0.0: |awk -F: '{print $2}'
# netstat -ntl |awk 'NR >2 {print $4}' |awk -F: '$0~"^0.0.0.0" {print $2}'

--这里用到了字符匹配

截取/etc/passwd前五行的倒数第二列

# awk -F: 'NR<=5 {print $(NF-1)}' /etc/passwd
head -5 /etc/passwd |awk -F: '{print $(NF-1)}'

练习:
cat 1.txt
1 2 3
1 2 3
cat 2.txt
a b c
a b c
要求得到结果
2 a c
2 a c

提示:paste

# paste 1.txt 2.txt |awk '{print $2"\t"$4"\t"$6}'

打印第五行

head -5 /etc/passwd |tail -1
awk 'NR==5  {print $0}' /etc/passwd
awk '{if (NR==5) print $0}' /etc/passwd

打印第五行的第五列:

head -5 /etc/passwd |tail -1 |cut -d":" -f5
awk -F: 'NR==5 {print $5}' /etc/passwd
awk -F: '{if (NR==5) print $5}' /etc/passwd

打印第五行和第六行:

awk 'NR==5 || NR==6 {print $0}' /etc/passwd
awk 'NR>=5 && NR<=6 {print $0}' /etc/passwd

练习:

找出/etc/以.conf结尾的文件的名字(如:kernelcap-2.6.18-164.el5.conf,只需要得到kernelcap-2.6.18-164.el5就可以了)

find /etc/ -name "*.conf" | awk -F/ '{print $NF}' |awk -F".conf" '{print $1}'

打印每一行的最后一列(可以以/etc/passwd文件为例,以下相同)

awk -F: '{print $NF}' /etc/passwd


打印每行的字段数

awk -F: '{print "第"NR"行的列数为"NF}' /etc/passwd

打印第五行的字段数

awk -F: 'NR==5 {print "第"NR"行的列数为"NF}' /etc/passwd

打印字段数大于6的行

awk -F: 'NF>6 {print $0}' /etc/passwd

打印最后一行

tail -1 /etc/passwd
awk  'END {print $0}' /etc/passwd

打印最后一行的最后一列

awk -F: 'END {print $NF}' /etc/passwd

打印前五行

awk 'NR<=5 {print $0}' /etc/passwd

打印五到十行,并在前面加上行号

awk 'NR>=5 && NR<=10 {print NR,$0}' /etc/passwd

打印奇数行 (删除偶数行)

awk 'NR%2==1 {print NR,$0}' /etc/passwd

打印偶数行 (删除奇数行)

awk 'NR%2==0 {print NR,$0}' /etc/passwd

对/etc/passwd里的用户做分类,分成管理员,系统用户,普通用户(只显示用户名,用awk)

awk -F: '$3==0 {print $1}' /etc/passwd
awk -F: '$3>0 && $3<500 || $3==65534 {print $1}' /etc/passwd
awk -F: '$3>=500 && $3!=65534 {print $1}' /etc/passwd
awk -F: '$3==0 {print "管理员有:"$1} $3>0 && $3<500 || $3==65534 {print "系统用户有:"$1} $3>=500 && $3!=65534 {print "普通用户有:"$1}' /etc/passwd

找出每天18:30之前下班的打卡记录
张三  2013-7-01 18:19:28
张三  2013-7-02 17:58:45
张三  2013-7-03 22:41:47
张三  2013-7-04 22:15:23
张三  2013-7-05 19:12:27
张三  2013-7-06 19:03:09
张三  2013-7-07 19:09:44
张三  2013-7-08 19:04:45
张三  2013-7-09 18:39:28
张三  2013-7-10 18:24:48
张三  2013-7-11 18:58:21
张三  2013-7-12 18:36:22
张三  2013-7-13 19:23:46
张三  2013-7-14 19:02:41
张三  2013-7-15 19:00:09
张三  2013-7-16 18:36:13
张三  2013-7-17 18:36:40
张三  2013-7-18 19:00:00
张三  2013-7-19 18:31:18
张三  2013-7-20 18:44:01
张三  2013-7-21 18:37:12

张三  2013-7-22 18:29:33

# awk -F"[: ]*" '$3==18 && $4<30 || $3<18 {print $0} '  3.txt

# awk '$3<"18:30:00" {print $0}' 3.txt	--时间直接比较是可以的,但是如果你小时为个位数(比如9:00:00,你应该要写成09:00:00才可以直接比)

# awk -F"[ :]*" '$3$4<=1830 {print $0}' 3.txt 

假设9点整上班,算出下面这几天这几个人分别迟到多少次,和扣多少钱(一次扣10块)

张三 2013-8-25 09:19:28
李四 2013-8-25 08:58:45
王五 2013-8-25 08:41:47
马六 2013-8-25 09:12:52
田七 2013-8-25 09:01:47
张三 2013-8-24 08:49:28
李四 2013-8-24 08:54:45
王五 2013-8-24 09:11:47
马六 2013-8-24 09:02:52
田七 2013-8-24 09:04:47
张三 2013-8-23 09:29:28
李四 2013-8-23 08:57:45
王五 2013-8-23 08:41:47
马六 2013-8-23 09:08:52
田七 2013-8-23 09:09:47
张三 2013-8-22 09:24:28
李四 2013-8-22 09:16:45
王五 2013-8-22 09:11:47
马六 2013-8-22 08:52:52

田七 2013-8-22 08:44:47

cat 2.txt | awk '$3>"09:00:00" {print $1}' |sort |uniq -c |awk 'BEGIN {print "姓名\t迟到次数\t应扣金额(元)"} {print $2"\t"$1"\t\t"$1*10"元"} '
姓名	迟到次数	应扣金额(元)
张三	3	30元
李四	1	10元
王五	2	20元
田七	3	30元
马六	3	30元

计算一个文件以一个分隔符分隔后的所有的列数的总和,并打印出来
--提示:awk是由上往下一行一行的扫描,类似写shell脚本时的循环语句,在这里是自动循环
--思路:先定义一个变量值为0,每扫一行,就加上那一行的列数(NF),最后打印出结果

sum=0
for i in 行数
do
sum=sum+每一行的列数
done
echo 总列数

awk -F: 'BEGIN {sum=0} {sum=sum+NF}END {print sum}' /etc/passwd

打印列数大于5的总行数

sum=0
for i in 行数
do
if [ NF -gt 5] && sum=sum+每一行的行数
done
echo 总行数

awk -F: 'BEGIN {sum=0} NF>5 {sum=sum+1} END {print sum} ' /etc/passwd
awk -F: 'BEGIN {sum=0} { if (NF>5) sum=sum+1} END {print sum} ' /etc/passwd
awk -F: 'BEGIN {sum=0} {NF>5 && sum=sum+1} END {print sum} ' /etc/passwd

打印列数大于5的总行数和总列数

awk -F: 'BEGIN {line=0;field=0} NF>5 { line=line+1;field=field+NF} END {print "大于5的总行数为"line"\n大于5的总列数为"field}' /etc/passwd	--正确的写法

awk -F: 'BEGIN {line=0;field=0}{ NF>5 && line=line+1;field=field+NF} END {print "大于5的总行数为"line"\n大于5的总列数为"field}' /etc/passwd	--错误的写法,因为这里NF>5的条件只影响到了line没有影响到field

awk -F: 'BEGIN {line=0;field=0} { if (NF>5)  line=line+1; field=field+NF} END {print "大于5的总行数为"line"\n大于5的总列数为"field}' /etc/passwd	--错误的写法,因为这里NF>5的条件只影响到了line没有影响到field

awk -F: 'BEGIN {line=0;field=0}{ NF>5 && line=line+1;NF>5 &&field=field+NF} END {print "大于5的总行数为"line"\n大于5的总列数为"field}' /etc/passwd	--正确写法

awk -F: 'BEGIN {line=0;field=0} { if (NF>5)  line=line+1; if (NF>5) field=field+NF} END {print "大于5的总行数为"line"\n大于5的总列数为"field}' /etc/passwd	--正确写法

打印列数大于5小于8,并且行数为奇数行的总行数和总列数

awk -F: 'BEGIN {line=0;field=0} NF>5 && NF<8 && NR%2==1 {line=line+1;field=field+NF} END {print "总行数为:"line"\n总列数 为:"field}' /etc/passwd

统计/etc/passwd一共出现了多少次bash字符 (要求用awk)
# grep -c bash /etc/passwd
# grep -o bash /etc/passwd |wc -l
# awk -F"bash" 'BEGIN{sum=0} {sum=sum+NF-1} END {print sum}' /etc/passwd

======================================================================

--awk外部脚本

脚本的结构

BEGIN {
}
      {
}

END {
}

例 :把 awk -F: '{print $1}' /etc/passwd 改成写外部脚本的形式

vim 1.awk

BEGIN {
FS=":"
}
{
print $1
}
END {
}

# awk -f 1.awk  /etc/passwd

例:  打印字段数大于5的总行数  (用脚本写)
awk -F: 'BEGIN {sum=0} NF>5 {sum=sum+1} END {print sum} ' /etc/passwd
awk -F: 'BEGIN {sum=0} {if (NF>5) {sum=sum+1}} END {print sum}' /etc/passwd

BEGIN {
sum=0
FS=":"
}
NF>5{   --注意这个条件和 { 符号要在同一行才可以
sum=sum+1
}
END {
print sum
}

BEGIN {
     FS=":"
     sum=0
}

{
        if (NF>5) --或者把这两行写成  NF>5 && sum=sum+1  
        sum=sum+1    
}

END {
        print sum
}

打印列数大于5小于8,并且行数为奇数行的总行数和总列数(用awk脚本写)

awk -F: 'BEGIN {line=0;field=0} NF>5 && NF<8 && NR%2==1 { line=line+1 ;field=field+NF } END {print "符合的总行数为:"line"\n符合的总列数为:"field}' /etc/passwd

BEGIN {
FS=":"
line=0
field=0
}
{
if (NF>5  && NF<8 && NR%2==1 )
{line=line+1; field=field+NF}
}
END {
print line"\n"field
}

BEGIN {
FS=":"
line=0
field=0
}
NF>5 && NF<8 && NR%2==1 {
line=line+1
field=field+NF
}
END {
print "符合的总行数为:"line"\n符合的总列数为:"field
}

=======================================

1,监控磁盘使用率,高于80%的找出来,输出警告,发送邮件给管理员

df |awk -F"[ %]*" '1<NR&&$5>=80{print $1"没容量了"}'|mail -s "fdisk" root

df -h |grep -v Filesystem |awk -F% '{print $1}'|awk '$5>80 {print $1"is used "$5"warning!!!"}' |sendmail root

df -k |awk '$3/$2>0.8 {print $1"的磁盘使用率为"$3/$2*100"%"}'  |mail -s "disk overuse" root

df -h |awk -F"[% ]*" '$1~"dev" && $5>80 {print $1"磁盘使用率高于80%,警告!!!"}' |mail -s "disk overuse" root

--上面的比较用纯数字比较(使用>=80这种,而不要使用>=80%),因为象100%>=80%得到的结果会为false,也就是说它从第一位开始比较的(因为1小于8)

--如果有逻辑卷的分区,那么他会显示两行,你可以使用df -P来显示为一行再来做(在rhel6.5版本中,默认已经是一行了,不是两行)
--上面的脚本实际情况你可以放到crontab里,然后做一个判断,如果找出来的为空,则不发邮件;找出来的不为空,那就表示有超过80%使用率的磁盘了,就发邮件;或者是lvm的话,可以做成使用率超过了就自动加空间到LVM分区里

2,监控CPU 15分钟内的平均负载,如果超过5则发警告邮件给管理员

uptime |awk '$NF>5 {print "15分钟内CPU的平均负载超过5"}' | mail -s "warning!" root

3,计算swap总量,使用量,剩余量,使用百分比,剩余百分比 (使用awk)

格式要求为:
总量 使用量 剩余量  使用率     剩余率
xxxxx xxxx xxxx xxx%  xxx%

# free |tail -1 |awk '{print "总量\t使用量\t剩余量\t使用率\t剩余率"} {print $2"\t"$3"\t"$4"\t"$3/$2*100"%\t"$4/$2*100"%"} '

扩展;
打印出
内存总量 内存使用量  内存剩余量 缓存总量  真实内存使用量 真实内存剩余量
xxxxx xxxx   xxxxx xxxx  xxxxxx xxxxxx

# free |awk 'BEGIN{print "内存总量\t内存使用量\t内存剩余量\t缓存总量\t真实内存使用量\t真 实内存剩余量"} NR==2{printf $2"\t\t"$3"\t\t"$4"\t\t"$5+$6+$7"\t\t"} NR==3 {printf $3"\t\t"$4"\n"}'
内存总量 内存使用量 内存剩余量 缓存总量 真实内存使用量 真实内存剩余量
8089928 1030136 7059792 492680 537456 7552472

4,把系统上ssh的登录成功日志格式化打印成类似下面的

*********************************************************
time            hostname        user    ip              port    protocol
Jul-15 15:47:20 li              root    2.2.2.35        6703    ssh2
*********************************************************
*********************************************************
time            hostname        user    ip              port    protocol
Jul-15 15:47:27 li              root    2.2.2.35        6704    ssh2
*********************************************************

# cat /var/log/secure |grep Accepted |awk '{print "***********************************************************************"} {print "time\t\thostname\tuser\tip\t\tport\tprotocol"} {print $1"-"$2,$3"\t"$4"\t\t"$9"\t"$11"\t"$13"\t"$14} {print "***********************************************************************"}'

也可以用下面这种格式,看起来舒服点
时间 主机名头 用户名 IP 端口 协议
Jan-7 17:54:36 server1 root 172.16.2.246 46729 ssh2
Jan-7 17:56:07 server1 root 172.16.2.246 46730 ssh2
Jan-7 18:00:46 server2 root 172.16.2.246 46731 ssh2
Jan-7 18:36:06 server1 root 172.16.2.247 48411 ssh2
Jan-8 00:05:17 server1 root 172.16.2.247 49205 ssh2
Jan-9 14:38:40 li root 172.16.2.35 47666 ssh2
Jan-9 14:40:06 li root 172.16.2.35 47668 ssh2
Jan-9 01:50:36 server1 root 172.16.2.247 44951 ssh2

# cat /var/log/ssh |grep Accepted |awk 'BEGIN {print "时间\t\t主机名\t\t用户名\t客户IP\t\t端口\t协议版本"} {print $1"-"$2,$3"\t"$4"\t\t"$9"\t"$11"\t"$13"\t"$14}'

扩展:把上面第二种处理的日志信息,导入到mysql的一张表里

处理完格式,然后使用mysqlimport导入就可以(过程省略)

扩展:不是象上面那样定期处理日志,再导入mysql,而是实现只要有人ssh登录,就直接把登录信息insert到mysql的表里
用户名 时间     from where
user1   2015-08-01 10:55:30    10.1.1.9

mysql> create table login (
    -> username varchar(30),
    -> date date,
    -> time time,
    -> clientip varchar(15));
Query OK, 0 rows affected (0.06 sec)

mysql> desc login;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| username | varchar(30) | YES  |     | NULL    |       |
| date     | date        | YES  |     | NULL    |       |
| time     | time        | YES  |     | NULL    |       |
| clientip | varchar(15) | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+

# vim /tmp/user_login_mysql.sh

#!/bin/bash

clientip=`last |head -1 |awk '{print $3}'`

if [ $clientip = ":0" -o $clientip = ":0.0" ];then
        clientip=local
fi

/usr/local/mysql/bin/mysql -u root -p123 <<EOF &>/dev/null
insert into aaa.login values('$USER',current_date(),current_time(),'$clientip');
EOF

# chmod 755 /tmp/user_login_mysql.sh --给执行权限

# vim /etc/profile  --在最后加上执行这个脚本的一句就可以了

sh /tmp/user_login_mysql.sh

5,read输入一个目录,精确计算这个目录里所有普通文件(不包括目录)(包括子目录里的文件)的大小之和(要算的是字节总和,不是所有的占用的块空间大小总和)

#!/bin/bash

read -p "输入一个目录:" dir

if [ ! -d $dir ];then
echo "不是目录,重试"
sh $0
exit 1
fi

方法一:
find $dir -type f -exec ls -l {} \; | awk 'BEGIN{sum=0} {sum=sum+$5} END {print sum}'

方法二:
find $dir -type f |xargs ls -l | awk 'BEGIN{sum=0} {sum=sum+$5} END {print sum}'

方法三:
ls -l `find $dir -type f` | awk 'BEGIN{sum=0} {sum=sum+$5} END {print sum}'

方法四:
sum=0
for i in `find $dir -type f`
do
        a=`ls -l $i |awk '{print $5}'`
        sum=$[$sum+$a]  
done
echo $sum

方法五:
ls -lR $dir |grep ^- | awk 'BEGIN{sum=0} {sum=sum+$5} END {print sum}'

6,找出目录下(包括子目录下)的最大的普通文件和最小的普通文件,输出所有普通文件的平均大小

#!/bin/bash

read -p "输入一个目录:" dir

if [ ! -d $dir ];then
echo "不是目录,重试"
sh $0
exit 1
fi

方法一:
# ll -S -r  $dir |awk 'BEGIN {sum=0} NR==2 {print "最小文件为:"$NF" 其大小为:"$5} {sum=sum+$5} END {print "最大文件为:" $NF" 其大小为:"$5"\n平均大小为:"sum/(NR-1)}'

方法二:
# find $dir -type f |xargs ls -lS | awk 'BEGIN {sum=0} NR==1 {print " 最大文件为:"$NF" 其大小为:"$5} {sum=sum+$5} END {print "最小文件为:" $NF" 其大小为:"$5"\n平均大小为:"sum/NR}'

未经允许不得转载:好玩吧 » linux常用命令-awk使用