下面的命令计算所有的C文件,CPP文件和H文件的文件大小总和。
1
2
|
$
ls
-l *.cpp *.c *.h |
awk
'{sum+=$5} END {print sum}'
2511401
|
我们再来看一个统计各个connection状态的用法:(我们可以看到一些编程的影子了,大家都是程序员我就不解释了。注意其中的数组的用法)
1
2
3
4
5
6
7
|
$
awk
'NR!=1{a[$6]++;} END {for (i in a) print i ", " a[i];}'
netstat
.txt
TIME_WAIT, 3
FIN_WAIT1, 1
ESTABLISHED, 6
FIN_WAIT2, 3
LAST_ACK, 1
LISTEN, 4
|
再来看看统计每个用户的进程的占了多少内存(注:sum的RSS那一列)
1
2
3
4
5
6
|
$
ps
aux |
awk
'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'
dbus, 540KB
mysql, 99928KB
www, 3264924KB
root, 63644KB
hchen, 6020KB
|
在上面我们可以看到一个END关键字。END的意思是“处理完所有的行的标识”,即然说到了END就有必要介绍一下BEGIN,这两个关键字意味着执行前和执行后的意思,语法如下:
BEGIN{ 这里面放的是执行前的语句 }
END {这里面放的是处理完所有的行后要执行的语句 }
{这里面放的是处理每一行时要执行的语句}
为了说清楚这个事,我们来看看下面的示例:
假设有这么一个文件(学生成绩表):
1
2
3
4
5
6
|
$
cat
score.txt
Marry 2143 78 84 77
Jack 2321 66 78 45
Tom 2122 48 77 71
Mike 2537 87 97 95
Bob 2415 40 57 62
|
我们的awk脚本如下(我没有写有命令行上是因为命令行上不易读,另外也在介绍另一种用法):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
$
cat
cal
.
awk
#!/bin/awk -f
#运行前
BEGIN {
math = 0
english = 0
computer = 0
printf
"NAME NO. MATH ENGLISH COMPUTER TOTAL\n"
printf
"---------------------------------------------\n"
}
#运行中
{
math+=$3
english+=$4
computer+=$5
printf
"%-6s %-6s %4d %8d %8d %8d\n"
, $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
printf
"---------------------------------------------\n"
printf
" TOTAL:%10d %8d %8d \n"
, math, english, computer
printf
"AVERAGE:%10.2f %8.2f %8.2f\n"
, math
/NR
, english
/NR
, computer
/NR
}
|
我们来看一下执行结果:(也可以这样运行 ./cal.awk score.txt)
1
2
3
4
5
6
7
8
9
10
11
|
$
awk
-f
cal
.
awk
score.txt
NAME NO. MATH ENGLISH COMPUTER TOTAL
---------------------------------------------
Marry 2143 78 84 77 239
Jack 2321 66 78 45 189
Tom 2122 48 77 71 196
Mike 2537 87 97 95 279
Bob 2415 40 57 62 159
---------------------------------------------
TOTAL: 319 393 350
AVERAGE: 63.80 78.60 70.00
|
即然说到了脚本,我们来看看怎么和环境变量交互:(使用-v参数和ENVIRON,使用ENVIRON的环境变量需要export)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$ x=5
$ y=10
$
export
y
$
echo
$x $y
5 10
$
awk
-
v
val=$x
'{print $1, $2, $3, $4+val, $5+ENVIRON["y"]}'
OFS=
"\t"
score.txt
Marry 2143 78 89 87
Jack 2321 66 83 55
Tom 2122 48 82 81
Mike 2537 87 102 105
Bob 2415 40 62 72
|
最后,我们再来看几个小例子:
1
2
3
4
5
6
7
8
|
#从file文件中找出长度大于80的行
awk
'length>80'
file
#按连接数查看客户端IP
netstat
-ntu |
awk
'{print $5}'
|
cut
-d: -f1 |
sort
|
uniq
-c |
sort
-nr
#打印99乘法表
seq
9 |
sed
'H;g'
|
awk
-
v
RS=
''
'{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'
|
关于其中的一些知识点可以参看gawk的手册:
内建变量,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din-Variables
流控方面,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Statements
内建函数,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din
正则表达式,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Regexp
(全文完)