查看原文
其他

Perl 语言输入、输出怎么写?控制结构如何用?看这一篇就够了!

晨光 生信者言 2022-03-29


转眼我们perl零零八系列已经有了五次知识点讲解,并配以两次实例精讲。不知道大家是否已经开始自己写脚本啦?


在上一节Perl编程课程中,我们介绍了Perl字符串操作,并结合一个实例进行讲解。从该实例中我们可以看到,Perl程序一般会有输入和输出文件,而且会用到while等循环结构。


这一期,我们就来详细说说输出、输出和控制结构的使用。

《Perl零零八速成系列》(共8节课)主要是面向无Perl编程经验或者Perl语言初学者,介绍Perl的基本知识和实用编程技巧。晨光与你一路,轻松点亮编程技能,一跃成为特工级的Perl编程牛人!

【前情回顾】

《Perl零零八速成系列—字符串操作与排序》

《Perl零零八速成系列---数据结构入门》

《Perl零零八速成系列---哈希和子函数》

《化腐朽为神奇,编程语言不可错过之正则表达式》

《实例精解!如何从海量序列信息中提取目标序列》

《Perl零零八速成系列---字符串操作与排序》

《实用案例精讲!如何用perl写一个截序列的脚本?》


【本节内容】

本节内容包括Perl 语言的的输入、输出与控制结构。



一、输入与输出

 

1、读取标准输入

读取标准输入一般采用<STDIN>,也就是行输入操作符。在标量上下文中执行该操作时,将会返回标准输入中的下一行,例如:

 

$line= <STDIN>;                      #读取下一行

chomp($line);                        # 截取最后的换行符

 

chomp(= <STDIN>);               #习惯用法,效果同上

 

如果读到文件结尾,行输入操作符就会返回undef。这样的设计是为了配合循环使用,可以自然跳出循环:

 

while(defined($line=<STDIN>)){

       print "I saw $line";

}

 

然而,在实际运用过程中,这里的defined()函数可以省略,直接写成:

 

while(<STDIN>){

       print "I saw $_";             #所读取的行默认储存在特殊变量$_

}

 

这样看起来就简洁多了!

 

 

2、钻石操作符输入

 

钻石操作符(<>)是行输入操作符的特例,不过它不是从键盘取得输入,而是从用户指定的位置读取:

 

while(<>){

       chomp;                   #这里chomp会直接作用于$_

       print "It was $_ tha I saw!\n";

}

 

3、调用参数

 

前面我们介绍到@ARGV是Perl用来储存参数列表的特殊数组,钻石操作符可以查看@ARGV,然后决定该用哪些文件名。如果@ARGV是空的,就会改用标准输入流。所以再程序运行之后,只要未使用钻石操作符,就可以对@ARGV进行修改。我们可以指定特定的文件,而不管用户在命令行参数中指定了什么

 

@ARGV=qw(larry moe curly)             #强制让钻石操作符只读取这三个文件

while(){

       chomp;

       print "It was $_ tha I saw in some stooge-like file!\n";

}

 

4、输出到标准输出

 

常见的输出函数包括print、printf和sprintf等(详见:《Perl零零八速成系列---字符串操作与排序》)。


print操作符会读取后续列表中的所有元素,并把每一项依次送到标准输出,例如:print "Hello world!"。

 

而printf函数负责将格式化的字符串输出到选定的文件句柄。其默认文件句柄是 STDOUT(标准输出),printf 函数后面带有一个加有引号的负责格式规范的控制字符串。其后则是一系列由逗号隔开的参数,例如:

 

$user="Mike";

$days_to_die=30;

printf "Hello, %s; your password expires in %d days!\n", $user, $days_to_die;

 

运行结果:

Hello, Mike; your password expires in 30 days!

 

sprintf 函数可以将格式化后的字符串存放在变量里面,以便稍后使用。它的一种常见的用法就是格式化小数点后面具有特定精度的数字。例如:

 

my $money = sprintf "%.2f", 2.49997;

print "$money\n";           #输出结果:2.50

 

 

5、文件句柄及操作

 

文件句柄(filehandle)就是程序里代表Perl进程(process)与外界之间的I/O联系的名称。也就是说,它是“这种关系”的名称,不是文件的名称。句柄的命名与其他变量命名规则一样,必须是以字母、数字及下划线组成,但不能以数字开头。有6个特殊文件句柄名是Perl保留的,它们是:STDIN、STDOUT、STDERR、DATA、ARGV以及ARGVOUT。

 

Perl可以使用open函数打开文件,例如:

#!/usr/bin/perl

open(FILE,"<file.txt") or die $!; 

#<表示只读方式,FILE为文件句柄用于读取文件

while(<FILE>){

   print "$_";

}

 

PS: 当Perl遇到致命错误时,可以用die函数来终止程序,并给出错误信息。

 

以下代码可以写入( > )文件:

open(FILE, ">file.txt") or die $!;

 

在文件使用完后,要关闭文件,以刷新与文件句柄相关联的输入输出缓冲区,关闭文件的语法如下:

 

close FILE;

  

二、控制结构

 

前面的课程里面介绍了while、if..else..和foreach控制结构的使用,这里我们将继续学习其它控制结构。

 

1、unless控制结构

 

我们在前面的课程学习到,在if控制结构中,只有当条件表达式为真时,才执行某块代码。与if相反,unless控制结构是当条件为假时执行指定代码,例如:

 

unless ($fred=~ /\A[A-Z_]\w*\z/i) {

print "The value of \$fred doesn't look like a Perl identifier name.\n";

}

 

使用unless意味着,要么条件为真,要么执行某块代码。这就好像使用if控制结构来判断相反的条件。另一种说法是它类似于独立的else子句。也就是说,当看不懂某个unless语句时,可以用如下的if语句来代替:

 

if ($fred =~ /^([A-Z_]\w*$/i) {

#什么都不做

} else {

print "The value of \$fred doesn't look like a Perl identifier name. \n";

}

 

2、until控制结构

 

while语句是当条件一直为真时,运行相应的代码,而与此不同的是,until 语句在给定条件为 false 时,重复执行语句或语句组,直到条件为真时,终止运行代码。

 

语法格式如下所示:

 

until(condition)

{

   statement(s);

}

 

3、for控制结构

 

Perl的for循环类似其他语言(如C语言),可用于多次执行一个语句序列,简化管理循环变量的代码,它的语法格式如下所示:

 

for ( 初始化; 测试; 递增 ){

   程序主体;

}

 

例如:

for ($i = 1; $i <= 10; $i++) { 

          # 1 数到10

print "I can count to $i!\n";

}

 

PS: 这里设置$i的初始值为1,$i小于等于10,所以执行花括号里面的语句,然后$i进行自增操作,重复进行判断并执行语句,直到不符合$i <= 10的条件时终止循环。

 

4、last操作符

 

Perl last 语句用于退出循环语句块,从而结束循环,last语句之后的语句不再执行,相当于循环的“紧急出口”,例如:

 

while (<STDIN>) {

if (/__END__/) {

# 表示结尾

last;

} elsif (/fred/){

print;

}

}

 

只要输入行中有__END__记号,这个循环就会结束。last操作符对整个循环起到终止作用,但是它只会对当前运行中的最内层的循环块发挥中用。

 

5、next操作符

 

Perl next操作不会立刻退出循环,而是结束当前这次循环迭代,并进入下一次迭代。例如:

 

#!/usr/bin/perl

 

$a = 10;

while( $a <15 ){

   if( $a == 12)

   {

       # 跳出迭代

       $a = $a + 1;

       next;

   }

   print "a 的值为: $a\n";

   $a = $a + 1;

}

 

运行结果:

a 的值为: 10

a 的值为: 11

a 的值为: 13

a 的值为: 14

 

 

6、redo操作符

 

Perl redo操作符能够将控制返回到当前循环块的顶端,而不经过任何条件测试,也不会进入下一次循环迭代。例如:

 

#打字测验

my @words =qw{ fred barney pebbles dino wilma betty };

my $errors =0;

 

foreach(@words) {

## redo 命令会跳到这里 ##

print "Type the word '$_': ";            #提示输入单词

chomp(my $try = <STDIN>);            #输入单词

if ($try ne $_) {                                   #判断单词是否正确

print "Sorry - That's not right.\n\n";

$errors++;

redo;                                             #跳到循环的顶端

}

}

print "You've completed the test, with $errors errors.\n";

 

PS: next与redo两者之间最大的区别在于,next会正常继续下一次迭代,而redo则会重新执行这次迭代。

 

本文尽量精简地介绍了Perl语言中输入输出与控制结构,并配上简单的示例供大家练习巩固。由于篇幅有限,难以深入展开说明,谨以此文,送与初入门Perl语言的朋友们。


下一节课我们将学习:文件测试与目标操作,敬请大家关注!

 


参考资料:

《Perl语言入门第六版(中文版)》

http://www.runoob.com/perl/perl-tutorial.html

http://www.runoob.com/try/runcode.phpfilename=HelloWorld&type=perl




 

/End.



欢迎加入生信者言交流群,和小伙伴们一起交流,入群请联系微信:genegogo007


推荐阅读

点击下方图片即可阅读

 

扫码关注,获取更多精彩内容

喜马拉雅FM搜索并订阅:生信者言;收听内容:

《一分钟听懂NGS基础概念》,让生信分析不再遥不可及

《亲爱的姑娘,你值得被温柔以待》,11个真实的人物故事

《众病之王:癌症传》,一起聆听人类对抗癌症的斗争史

回复文字:果然科学,看一篇好玩的科普文。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存