通向perl的旅程赵幸zhaoxing@genomics.cn134287558836458832011年6月24日可以学到什么仅仅是一个入门旅程全篇没有一条一条的语法通过例子了解perl的最基本的东西真正的学习只有靠自己去学习23Outline生物信息学简介Perl的魅力初识Perl认识Perl警惕小错误好习惯大家有安装Perl怎么去了解Perl4生物信息学的定义生物信息学(Bioinformatics)是一门交叉学科,它包括了生物信息的获取、处理、存储、分发、分析和解释等在内的所有方面,它综合运用了数学、计算机科学和生物学的各种工具,来阐明和理解大量数据所包含的生物学意义。5生物数据的特点固定格式的一组数据为单位:数据的展示方式也是固定的几种形式数据量大6例如某参考序列,有6千万行,格式如下,chr1NNNNNNNNNNNNNNNTCTAGTATTTTTAAGTATCTTTGAGGAAGAGCACTaTATTccTGTGAGAAAAAGTGGAccGTGGAATtTGAGCACTGCTAGTATCGTCAAGGATACTTCCACTTAGGGAGAGGCTAGGAAGTGACGGCTTAchr2TTCACGTAAATGGAAGATGATTCTAGTTTGGGATCCTAAAGCAGCATTAA为什么选择Perl好用在处理海量生物学数据很好用,可以写出快速、占用资源很少的程序。好学容易上手,容易写。7Perl的魅力介于低级语言和高级语言之间,脚本语言中执行速度最快8Perl几乎不受限制Perl很容易Perl的速度通常非常快Perl处理生物数据具有优势——Bioperl包初识Perl好用---不需要编译,写好即可运行一个linux下的Perl例子91、新建test.pl:vitest.pl2、输入#!/usr/bin/perlprintHello,world\n;3、保存退出::wq4、运行perltest.plWindows下记事本即可,推荐使用编辑器(EditPlus,UltraEdit,Notepad)运行-cmdperltest.plPerl程序的基本结构程序开头:#!/usr/bin/perl用来执行这个文件的程序路径10usestrict;#若开头使用,一定要用my声明变量。代码要以;结尾变量:$a=2;my$b;数组:@a=(1,2,3);哈希:%name=('gene1'=2838,'gene2'=2344);\n换行;\t制表符;\s空白认识Perl一.数据——Perl知道的数据二.控制结构——Perl的控制结构三.数组——最一般的四.哈希——特别一点的五.文件操作——怎样用Perl处理文件六.子程序——需要时写写七.强大的正则表达式八.强大的Perl包11Perl知道的数据标量、浮点7.25e-45:2**3:字符串$a=ab;$b=cd;$c=$a..$b;$d=length($c);@array=split(/\s+/,$c);127.25×10-4523$c=abcd;$d=5;@array=(ab,cd);比较操作符比较数值字符串相等==eq不等!=ne大于gt大于等于=ge小于lt小于等于=le13Perl的常用控制结构if控制语句my$x=5;if($x==5){printXmustbe5\n;}elsif($x==4){printXmustbe4\n;}else{printXisnot4or5\n;}14循环举例my$num=0;while($num10){$num+=2;print$num\n;#打印出246810}while(1){lastunless($num10);$num+=2;print$num\n;#打印出246810}15last:退出循环next:进入下一个循环redo:重新开始循环until的用法和while一样,只是意义刚好相反until($num10){print$num\n;$num=$num+2;}for循环和C语言的一样for($num=0;$num10;$num=$num+2){print$num;}16my@array=(1,4,3);数组元素个数增push@array,1,2;unshift@array,1,2;删mya=pop@array;my$b=shift@array;改查$number=@array;最一般的——数组17@array=(1,4,3,1,2);$array[3]=1;$array[4]=2;$a=3;@array=(1,4);@array=(2,1,1,4,3);$b=1;@array=(4,3);$array[0]=5;print$array[0];排序my@array=(1,4,3);按ASCII排序按数值(由小到大)按数值(由大到小)18my@new=sort@array;my@new=sort{$a=$b}@array;my@new=reversesort{$a=$b}@array;foreach遍历按行输出数组的每一个元素。my@array=(1,4,3);foreach(@array){print$_\n;}或者foreach$v(@array){print$v\n;}19my$a=0;for($a=0;$a@array;$a++){print“$array[$a]\n;}特别一点的——哈希%name=('gene1'=2838,'gene2'=2344)key键gene1;value值2838哈希长度添加或修改元素访问哈希删除元素判断某个元素是否存在访问整个哈希20$length=keys%name$name{'gene3'}=7836$b=$name{'gene1'}delete$name{'gene3'}exists$name{'gene3'}foreach或while等printmy@k=keys%name;printmy@v=values%name;访问整个哈希my%name=('gene1'=2838,'gene2'=2344,'gene3'=2567);whileforeach21while(my($key,$value)=each%name){print$key=$value\n;}foreach(keys%name){print$_=$name{$_}\n;}each:依次读取name中的对值while(my($key,$value)=each%name){lastif($keyeqgene2);print$key=$value\n;}则遇到keygene2之后,就退出循环了。但是假如之后又需要循环遍历这个name进行查找,即再次使用whileeach的话,会发现输出的结果不是从头开始,而是从上次last退出循环的下一处继续输出。foreach(sortkeys%name){print$_=$name{$_}\n;}22#!/usr/bin/perl-wusestrict;my%name=('gene1'=2838,'gene2'=2344,'gene3'=2567);print**firstwhicheach**\n;while(my($key,$value)=each%name){lastif($keyeqgene1);print$key=$value\n;}print**secondwhicheach**\n;while(my($key,$value)=each%name){print$key=$value\n;}23#!/usr/bin/perl-wusestrict;my%name=('gene1'=2838,'gene2'=2344,'gene3'=2567);print**firstforeach**\n;foreach(keys%name){lastif($_eqgene1);print$_=$name{$_}\n;}print**secondforeach**\n;foreach(keys%name){print$_=$name{$_}\n;}好用--处理文件:很少的代码,做很多的事情通过句柄操作大写(例如:INOUTFILE)open(IN,,Input_file);$ate=IN;#按行@ate=IN;#全部open(OUT,,OUT_file);printOUTAllisOK!\n;Perl中以下句柄是默认的:常用的:STDINSTDOUTSTDERRARGVperldocperlvar:查看关于perl内部变量的说明,包括以上句柄24@ate=IN;少用。如果文件很大,那么程序消耗的内存就会很大。通过句柄OUT把要写入文件里的信息和文件联系起来。使用print函数。按行读入文本文件Input_file,在每行最后加上\tOK字符串后输出open(IN,,Input.txt)while(1){$line=IN;lastunless($line);chomp$line;print$line\tOK\n;}25需要时写写子程序格式subsubname{...}调用:&subname;如果传进来有参数,参数的顺序$_[0]、$_[1]…26比较两个数的大小的函数submax{if($_[0]$_[1]){$_[0];}else{$_[1];}}$maxnumber=&max(2,8);27submax{my($a,$b)=@_;if($a$b){$a;}else{$b;}}如果找出一堆数中最大的数的子函数可以怎么写?小提示:巧用shiftforeach28$maxinum=&max(3,5,10,4,6);submax{@array=@_;my($max_so_far)=shift@array;foreach{@array}{if($_$max_so_far){$max_so_far=$_;}}$max_so_far;}好用---强大的正则表达式使用格式匹配字符串file:/file/或m/file/s/e/a/匹配并替换$string=i:love:perl;$string=~s/:/\*/g;#此时$string=i*love*perl;模式匹配$string==~s/(\d+)/$1*2/e;#(\d+)代表$string中的一个或多个数字字符,将这些数字字符执行*2的操作,因此最后$string变成了。29正则表达式的妙用例如计算data.txt文件中每条染色体中胞嘧啶的个数,假设文件很大。1.按行读2.区分染色体3.不分大小写,匹配碱基c4.读到最后一行,输出最后一条染色体的结果,并退出循环。5.何时输出结果。30#!/usr/bin/perlusestrict;my($number,$count,$print_flag)=(0)x3;my($line,$chr);open(IN,,dir/data.txt);while(1){$line=IN;chomp($line);unless($line){print$chr\t$number\n;last;}if($line=~/(^)([\w\d_]+)/){if($print_flag){print$chr\t$number\n;$number=0;}$chr=$2;$print_flag=1;next;}$count=+($line=~s/c/c/ig);$number=+$count;}#print_flag做为输出标记#(0)x3等同于(0,0,0)#按行读#去掉行尾的换行符#unless后面条件为假时执行。#读到最后一行,输出最后一条染色体的结果,并退出循环。#区分染色体,模式匹配#$1:(^);$2:(\w+\d+)#记录替换的次数/i不区分大小写/g依次操作,直至行尾。效率比把每行拆分成一个一个字符去匹配效率高。#记录总数好用---强大的