用SED打印斐波那契序列
整理邮件时看到了这个SED脚本(2006年1月),好像是我写的最后一篇关于SED的文章……
# 脚本开始
# SED打印斐波那契序列
# 调用:seq 10 | sed -f fib.sed # 打印前10个数字(运行较慢,不要打印太多)
# yes | sed -f fib.sed # 打印序列直到溢出
# 这个脚本用模拟的方式进行数字运算。有关这种方法的更
# 多细节可以参考Greg Ubben写的教程:
# http://sed.sourceforge.net/grabbag/tutorials/
1{
# 下面字母串的长度决定了可打印的序列长度
# 可以修改下面的字串使之支持更多的序列
# s/.*/zyxwvutsrqponmlkjihgfedcba/
s/.*/kjihgfedcba/
# 初始化序列为“1, 1”
s/.*/ &a &a /; h; d
}
# 从hs取最后两组数字串进行运算
g
s/.* \(.*\) \(.*\) $/\1\2/
# 进行进位操作前先对两组数字加总(其实是排序)
s/\(\(.\)\2*\)/\1 /g
:lpsort
s/\(\([^ ]\)\2\{0,\}\)\( .*\)\2/\1\2\3/
tlpsort
s/ //g
# 调整加总的结果
# 加总时我们进行如下运算:
# edcbaa + edcbaaa = edcbaaaa
# 1 + 2 = 3
# 但实际在加总(排序)后我们等到的结果是:
# edcbaa + edcbaaa = eeddccbbaaaaa
# 我们需要将eeddccbbaaaaa转换为edcbaaaa
s/\(.\)\(\1\{1,19\}\)/\2/g
# 进行进位操作。
# baaaaaaaaaaa进位后成为bba——10
:doCarry
s/\(.\)\(\(.\)\3\{9\}\)\3/\1\1\3/
t doCarry
# 简单(粗糙)的溢出检验
# 因为第一个字母如果超过9个说明没有正常进位——即溢出
/^\(.\)\1\{9\}/{g;s/$/ ++OVERFLOW++/; b2digi}
# 将这一轮的结果保存到hold space。记得在最后加上一个空格。
G
s/\(.*\)\n\(.*\)/\2\1 /
$!{h;d}
g
# 运算完后将模拟结果转为数字表示的结果
:2digi
s/\([a-z]\)\1\{9\}/9/g
s/\([a-z]\)\1\{8\}/8/g
s/\([a-z]\)\1\{7\}/7/g
s/\([a-z]\)\1\{6\}/6/g
s/\([a-z]\)\1\{5\}/5/g
s/\([a-z]\)\1\{4\}/4/g
s/\([a-z]\)\1\{3\}/3/g
s/\([a-z]\)\1\1/2/g
s/\([a-z]\)\1/1/g
s/\([a-z]\)/0/g
s/ 0*/ /g
# 溢出检验需要q命令
q
# 脚本结束
![hq00e[a]126.com](http://static.flickr.com/56/120355805_7079a475f9_m.jpg)


