2006年10月21日星期六

Shell, Sqlite,date和awk

上周写了有生以来最复杂的Shell程序,这个程序的目的是从一个文本文件生成各种统计信息。文本文件有1000多行,每行对应一条记录,每条记录有10来个域。统计的信息很多,比如一个长时间段内,某个域发生某种变化的记录总数的变化趋势。统计信息的种类最终是8项。

我决定拿Sqlite来作这个事情。Sqlite是个轻量级的数据库,它提供一个sqlite的命令行,通过它就能完成创建数据库、插入数据、查询等各种操作。我所要做的就是:
1.从原始数据文件,也就是那个文本文件,生成一个sql语句文件,进而用sqlite生成数据库;
2.生成查询统计信息的sql语句文件,然后用sqlite命令行进行查询。

在shell程序中使用sqlite很方便,首先需要生成这样的sql语句文件
sql语句文件sql.txt:
.output Somefile    // 这句话告诉sqlite把sql执行的结果输出到文件
create tab ...        // 正常的sql语句
insert into ....
.quit                // 告诉sqlite退出
然后,cat sql.txt | sqlite data.db。这样,sqlite就会执行sql.txt中的sql语句,并把结果保存到Somefile中。

从原始数据生成创建数据库的sql.txt,当然是awk最胜任了。我也是这次才发现awk如此的好用。在计算平均值的时候也只能求助于它,因为它不会把商取整。
echo "$a $b"|awk '{ print $1/$2 }'    #计算a/b的值

最后说说shell编程,如果能有选择的话,我肯定会挑python、tcl甚至ruby,这样代码至少会让减少70%,看起来也会更elegant。一开始在Linux上写这个脚本,把对日期的处理完全交给date命令了,但是最终脚本运行在solaris上时,才发现solaris上的date傻得可以,只好自己处理日期的增减变化。不过提醒一下各位如果你们在Linux山写脚本要涉及日期的处理时,大可以把这份脏活交给date命令来作。
比如你想看某个特定日期,比如说2005年10月1日,的前20天的日期,这么做就可以了:
date "+%D" --date="10/01/2005 20 days ago"

2006年10月20日星期五

Ruby的特性之四,MIXIN

好久没写了,Ruby和Rails也很久没碰了,不过我还是想把一开始学习Ruby和Rails的感觉写完。今天就是最后一个特性,Mixin。
先说C++的多重继承,这个东西不论是从逻辑上还是从实际运用上都容易把人搞晕,所以后来Java和C#都取消了多重继承,换之以接口。但是接口有个缺点,就是,它只是接口,不包括具体实现,继承接口的类需要自己实现接口定义的各种方法,很多时候这些方法的实现是大同小异的,程序员不得不一次次重复自己,repeat yourself已经是很痛苦的事情了,更不用说以后扩展维护的难度。
所以又出现了范型,generic programming。范型还不错,实现了数据类型无关的编程,这对很大一类问题都是很简单直接的解决办法,但是范型并没有很直接的解决继承接口无法继承实现的问题。并且,Ruby这样的动态语言本身就是数据类型无关的,并不需要范型这种东西,所以范型只是用来解救Java,C++和C#程序员的。
Ruby提供的Mixin可以说是最直接的解决了接口继承的缺点。Mixin就是带有实现的接口。举个最简单的例子吧。

module Mixin1
def fun1
print "I am fun1 from Mixin1"
end

def fun2
print "I am fun2 from Mixin1. I'll call a member function of the class which includes me"
mem_fun
end

def fun3
print "I am fun3 from Mixin1. I'll print out a member variable of the class which includes me"
print mem_var
end
end

class A
include Mixin1
def mem_fun
print "I am a member fun of class A"
end

def initialize
@mem_var ="I am a member varaible of class A
end
end

a = A.new
a.fun1
a.fun2
a.fun3

That's it!其实对于动态语言来说,实现这一点并不难,做到前面三点也不难,难的是Ruby把这些做的这么贴心,这么顺手,真难怪其异军突起。好了好了,我就不在这放马后炮了,希望各位have fun with it。下一篇我得讲讲shell编程了。