perl入门09:循环与控制

1、for/while/if

  • 后两者在前面的例子中均有说明,不再赘述了
  • for与foreach是等价的,即可以互换
    见一个简单例子
#!/usr/bin/perl -w
use strict;
for (my $i=1;$i<=10;$i++) {
# 分别为起始值、判定条件、变化规则
    print "$i\n"
}

or

#!/usr/bin/perl -w
use strict;
for (1..10){
    print "$_\n"
}

懒惰即美德,所以有时越简单越好,比如--
print "$n is a negative number\n" if ($n<0);
print "$_\n" for (1..10);
print "$_\n" while (<IN>);

2、循环控制

主要有两个--

  • next 表跳过,执行下一循环;
  • last 表在特定条件下终止循环;
#!/usr/bin/perl -w
use strict;
for (1..10) {
    if ($_==5) {
    next; #1234678910
    #last;  #1234
    } else {
       print "$_\n";
    }
}

例如在一个含有几万条序列的基因集中寻找某一特定基因,找到后即可终止,没有必要再执行。这一过程很好地结合了lastnext的使用。

while (<IN>) {
    chomp;
    if (exists $hash{$_}) {
        print "$_\n";
        last;   #找到后直接终止
    } else {
        next;  #跳过,执行下一循环
    }
}

3、elsif语句

  • 适用于分级别,等级,年龄段等可以是多种选择、归类的情况。
    下面一个例子是根据成绩分等级的经典例子
#!/usr/bin/perl -w
use strict;
print "Enter your score:";
chomp (my $score=<STDIN>);
#实现交互式输入

if ($score==100) {
    print "Excellent\n";
} elsif ($score >=90 && $score <100 ) {
    print "Very Good\n";
} elsif ($score >=80 && $score <90) {
    print "Good\n";
} elsif ($score >=70 && $score <80) {
    print "OK\n";
} elsif ($score >=60 && $score <70) {
    print "Pass\n";
} else {
    print "You need to work hard\n";
}

注意elsif的书写,不要写成elseif了。

补充1:if另一种写法

(<1>) ? <2> : <3> ;
若<1>为真就执行<2>,否则执行<3>

#!/usr/bin/perl -w
use strict;
print "Enter your score:";
chomp (my $score=<STDIN>);
my $result=
($score==100) ? "Excellent" :
($score >=90 && $score <100 ) ?  "Very Good" :
($score >=80 && $score <90  ) ?  "Good"      :
($score >=70 && $score <80  ) ?  "OK"        :
($score >=60 && $score <70  ) ?  "Pass"      : 
 "You need to work hard";

print "$result\n";

补充2:逻辑与或

  • && :两真才真(见上例)
    ( ) && ( ); 表示若左为真,就执行右

  • || :一真则真
    ( ) || ( ); 表示若左真,则不执行右;相反则执行右。
    $ARGV[1] || =20; 表示第二个参数不输入就默认为20,否则就按输入参数计算。

4、循环批量生成生信脚本例子

  • 目的:blast序列比对找同源序列,但是当序列文件过大相当耗时。可以将大文件拆分成多份小文件,进行多线程blast,可以大幅提高效率。最后将结果合并即可。
    grep ">" gene.ffn | wc 先了解gene中含有多少条序列,大概要分成多少份。
#!/usr/bin/perl -w
use strict;


my @seq=();  #定义空数组,存储序列
my $part||=50;  #设置默认分成50份
chomp (my $num=`grep ">" $ARGV[0] |wc -l`);  # -l 选项
my $i=1;
my $j=int ($num/$part);   #向下取整,求每份中包含的序列数


my $outdir="split";  #为小份序列文件创建存储文件夹
`mkdir $outdir`;
#语法见下补充

open IN,"$ARGV[0]";  #打开序列文件
$/=">";<IN>;
#此循环去除ID开头大括号,并将序列内的换行符删去,并最终将所有序列储存到一个数组中。
while (<IN>) {
    chomp;
    next if (/^>/);
    my ($id,$seq)=(split /\n/,$_,2)[0,1];
    $seq=~ s/\n//g;
    my $out="$id\n"."$seq";  #除了没有大于号,且序列无换行符,其余格式与fasta相同
    push @seq,$out; #push 添加
}
close IN;
$/="\n";  #更改分隔符
open SH,">blast.sh";   #批量脚本文件
# 循环思路例如4000条序列分成50份,每份近80条。
# 外循环为份数 50次
# 内循环为每份序列数 80次
for (my $i=1;$i<=$part;$i++) {
    open OU,">$outdir/split_$i.fa";
    foreach (0..$j-1) {
        my $out=shift @seq;   #每次在开头取一条序列
        print OU ">$out\n";   #按标准fasta格式写入到 $outdir/split_$i.fa 
    }
        print SH "blastall -i $outdir/split_$i.fa -d $ARGV[0] -o $outdir/split_$i.blast -m 8 -e 1e-5 -p blastn -a 2 -F F;\n";
        #每一次大循环即编写一个blast脚本
}
perl 1.pl gene.ffn
1.pl-1
1.pl-2

补充:`mkdir $outdir`; 是perl脚本中使用了Linux命令;使用方法就是在perl
脚本中,给Linux命令两边加上反引号 ` (Esc下面那个键)即可。例如

  • 创建目录
#!/usr/bin/perl -w
use strict;

chomp (my $pwd=`pwd`);   #注意有换行符,需要去掉
`mkdir $pwd/test`;
  • 记录脚本运行时间
#!/usr/bin/perl -w
use strict;
#记录脚本执行时间

my $start=`data +%Y-%m-%d-%R`;
#置于脚本开头

my $end=`data +%Y-%m-%d-%R`;
#置于脚本结尾
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • Python语言特性 1 Python的函数参数传递 看两个如下例子,分析运行结果: 代码一: a = 1 def...
    时光清浅03阅读 482评论 0 0
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,380评论 0 5
  • 刘小泽开始写于19.7.31写这个是因为看到龙星教程使用了大量的perl脚本,动辄4、5千行,例如https://...
    刘小泽阅读 4,338评论 2 50
  • Python语言特性 1 Python的函数参数传递 看两个如下例子,分析运行结果: 代码一: a = 1 def...
    伊森H阅读 3,055评论 0 15
  • 躺在夜的床上 脑海里嘈杂着几十台机器 眼睑隔断两重黑暗 惊悚中,我突然睁开双眼 除了钟表的滴答 我听到了全世界的叹息
    阿磊_6812阅读 111评论 0 0