利用 AWK 的数值计算功能提升工作效率(2)快速计算两个文件之间的时间差
- UID
- 1066743
|
利用 AWK 的数值计算功能提升工作效率(2)快速计算两个文件之间的时间差
实例1: 快速计算两个文件之间的时间差如果仅仅从事单纯的数值计算, 恐怕 awk 不是我们最好的选择, 毕竟 awk 是为了方便文本处理而设计的。 不过如果数值计算和文本有密切关系的话, 比方说计算之前要先处理文本中的数据 (如查找,提取数据), 这时 awk 的优势就会充分显示出来。 而这样的情况在工作中往往是经常碰到的。 我们来看一个实际的例子。 假定我们要比较某些运行在 Linux 集群上的并行程序的效率, 一个可行的方法是估算这些程序运行所需的时间。 这些程序运行的时间通常比较长, 可以从 10 几个小时到一个多星期。 注意到程序在运行中会不断地生成数据文件, 而 Linux 系统会纪录下每个数据文件被创建 (如果以前不存在) 或修改(如果以前存在) 的时间, 这样就可以通过计算两个文件的时间差来估计并行程序的效率。 我们知道 Linux 提供的 stat 命令可以用来获取某个文件的各种属性, 比如对数据文件 simu_space_1.dat 使用命令 stat simu_space_1.dat 会有如下的输出:
清单 7. 命令 stat simu_space_1.dat 的输出1
2
3
4
5
6
7
| File: "simu_space_1.dat"
Size: 237928 Blocks: 480 IO Block: 4096 regular Datei
Device: 801h/2049d Inode: 2768915 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ nst) Gid: ( 1000/ nst)
Access: 2008-11-14 10:56:05.000000000 +0100
Modify: 2008-11-13 23:26:44.000000000 +0100
Change: 2008-11-13 23:26:44.000000000 +0100
|
以上输出包含了关键字 ’Modify’ 的一行中纪录下了文件被修改的时间。 所以原则上说只要对两个文件分别使用 stat 命令, 得到它们的修改时间, 就可以计算出它们之间的时间差。 如果计算的次数很少的话, 这个工作当然可以手工完成。 不过要频繁计算的话就很费时间了, 而且出错的几率也会变大。 这种情况下我们可以求助 awk, 让它来自动完成这个计算工作, 为此我们创建了下面的脚本 time_df.awk:
清单 8. 计算时间差的 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
25
26
27
28
29
30
31
32
| BEGIN {
n = 0;
d1 = 0;
s1 = 0;
FS = ":|-| *";
}
{
for(i=1; i<=NF; i++)
{
if($i~/Modify/)
{
n = n + 1;
d = $(i+4);
h = $(i+5);
m = $(i+6);
s = $(i+7);
d1 = d1 + ((-1)**n)*d*24*3600;
s1 = s1 + ((-1)**n)*(3600*h + 60*m + s);
}
}
}
END {
s1 = s1 + d1;
D = int(s1/(24*3600));
H = int((s1 - D*24*3600)/3600);
M = int((s1-D*24*3600-H*3600)/60);
S = s1 % 60;
printf("The total time required %d days, %d hours, \
%d minutes and %d seconds\n", D, H, M, S) ;
}
|
上面的代码是基于如下的考虑: 首先使用 awk 找到包含 ’Modify’ 关键字的那一行, 然后把其中有关日期和时间的数据提取出来。 由于直接对日期和时间做减法不是很方便, 所以先把日期和时间转化为一个以秒为单位的数字 (从每个月的第一天0时0分0秒算起)。 容易理解, 由两个数字相减得到的时间差也是以秒为单位的。 为了能直观显示, 输出时再把这个时间差表达为天, 小时, 分钟和秒。 要计算两个文件 simu_space_1.dat 和 simu_space_100.dat 之间的时间差,可以用下面的命令:
清单 9. 计算文件时间差的命令1
| stat simu_space_1.dat simu_space_100.dat | awk -f time_df.awk
|
先生成的文件 simu_space_1.dat (也就是时间较早一些的) 放在前面,后生成的文件simu_space_100.dat 放在后面。 如果要算另外两个文件之间的时间差, 只要换一下文件名就可以了。 借助于上面的 awk 代码我们可以快速且精确地得到任意两个数据文件的时间间隔。 需要指出的是, 上面的程序没有考虑跨月度这种情况。 也就是说, 如果第一个数据文件是在某个月的月末生成, 而第二个文件是在下个月的月初生成, 这时就不能用它来计算, 因为得到的时间是没有意义的负数。 |
|
|
|
|
|