生物信息编程生信相关生信学习

生信~一天学会Perl,你相信吗?

2019-07-31  本文已影响120人  刘小泽

刘小泽开始写于19.7.31
写这个是因为看到龙星教程使用了大量的perl脚本,动辄4、5千行,例如https://github.com/WGLab/PennCNV/blob/master/filter_cnv.pl
题目不是我取的,我也不知道学不学的会,但总要试试,教程在:Perl Tutorial for Beginners: Learn in 1 Day https://www.guru99.com/perl-tutorials.html

前言


Perl 变量

什么是变量?

可以将变量想象成一类容器,能存储一个或多个值。一旦指定了值,那么这个变量的类型也就确定了,但是其中的值是可以不断改变的

三类变量:

标量(scalar)
数组(Array)
哈希(Hashes)

Perl的条件使用

和大多数其他语言一样,都会涉及不同的条件语法

if条件

my $a=5;
if($a==5)
{
   print "The value is $a";
}
# 输出5

if else条件

就是加多一个限制条件

my $a=10;
if($a==5)
{
    print "The values is $a ---PASS";
}
else
{
    print "The value is $a ---FAIL";
}
# 结果 The value is 10 ---FAIL

elseif条件

my $a=5;
if($a==6)
{
    print "Executed If block -- The value is $a";
}
elsif($a==5)
{
    print "Executed elsif block --The value is $a";
}
else
{
    print "Executed else block – The value is $a";
}

if嵌套

my $a=11;
if($a<10){
  print "Inside 1st if block";
        if($a<5){
                print "Inside 2nd if block --- The value is $a";
        }
        else{
                print " Inside 2nd else block --- The value is $a";
        }
    }
    else{
            print "Inside 1st else block – The value is $a";
    }
# Inside 1st else block – The value is 11

unless

它和if的意思是相反的,只有当它包含的条件为假时,才会执行它的命令(可以和if对照理解);如果满足unless的条件,那么就会执行它的else命令

my $a=5;
unless($a==5)
{
   print "Inside the unless block --- The value is $a";
}
else
{
   print "Inside else block--- The value is $a";
}
# 结果是:Inside else block--- The value is 5

Perl循环使用

主要是四种:for, foreach, while and until

for循环

当条件满足时执行,例如:

my @array=(1..10);
for(my $count=0;$count<10;$count++)
{
    print "The array index $count value is $array[$count]";
    print "\n";
}
# 这个结果会返回类似"The array index 0 value is 1"的10条结果

for的第二种用法

for(1..10)
{
    print "$_ n";
    print "\n";
}
# 结果会输出1n、2n等,且都是间隔一行

foreach

它就是在for的基础上增加递归,不用手动设定

my @array=(1..10);
foreach my $value (@array)
{  
    print " The value is $value\n";
}
# 先定义一个数组,然后将数组放入foreach循环,每次循环赋值给value

# 另一种展现方式:利用$_(更常用一点)
my @array=(1..10);
foreach(@array)
{
    print " The value is $_ \n"; 
}

上面是对数组进行foreach操作,那么对哈希呢?

my %hash=( 'Tom' => 23, 'Jerry' => 24, 'Mickey' => 25);
foreach my $key (keys %hash)
{
print "$key \n";
}

#参考上面数组的第二种,我们对哈希也能写出
my %hash=( 'Tom' => 23, 'Jerry' => 24, 'Mickey' => 25);
foreach(keys(%hash))
{
print "$_ \n";
}
# 依次类推,对value也可以调用

while

只有当满足while的条件时才进行循环,不满足就跳出。例如:猜数字的小程序

#!/usr/bin/perl
$guru99 = 0;
$luckynum = 7;
print "Guess a Number Between 1 and 10\n";
$guru99 = <STDIN>;
while ($guru99 != $luckynum)
{
    print "Guess a Number Between 1 and 10 \n ";
    $guru99 = <STDIN>;
}
print "You guessed the lucky number 7"
# <STDIN>就是键盘输入的数字,如果不等于提前设定的$luckynum=7时,就循环,让你一遍一遍输入,只有输入为7时,才输出恭喜信息

do while循环

要把do和while当成一个整体,语法结构是:

$guru99 = 10;
 do {
 print "$guru99 \n";
 $guru99--;
 } 
 while ($guru99 >= 1);
 print "Now value is less than 1";
 # 意思是从10递减1,一直减到1,当等于1时还是满足while条件的,那么继续传给do循环,再减1为0。此时不再满足while条件,于是跳出循环,输出结果

until循环

和条件控制的unless很像,当其中的条件为假时才跳出输出

大体语法如下:

print "Enter any name \n";
 my $name=<STDIN>;
 chomp($name);
 until($name ne 'sai')
 {
    print "Enter any name \n";
    $name=<STDIN>;
    chomp($name);
 }
 # 只有当until($name ne 'sai')中的条件$name ne 'sai'为假,也就是$name=sai时才会结束

这个<STDIN> 要注意一下:它用作非文件的标准输入,例如管道传输的数据、重定向的数据或者键盘输入。而且它的输入会自带换行符,因此print不需要加额外的换行符。(读取文件内容用<> )还有chmop 是去掉行尾换行符的意思

Perl运算符(Operator)

Perl整合了C语言的许多运算符,相对于其他语言运算符的数量更多。主要包括:数学运算、赋值、逻辑关系符号

Perl特殊变量

特殊之处就在于:有的变量提前定义好了,然后长得比较奇怪,但是用起来很方便。大部分的特殊变量都是标量变量

Perl正则表达式

字符串匹配是perl强大的一个原因,虽然现在perl在一点点被遗忘,但是很多好用的脚本还是在流传。好的东西不会被淡忘~

perl 比对用m//,替换用s///

先复习一下表达式
\   表示特殊字符或引用
* 0或多
+ 1或多
?0或1
| 可选的匹配模式
() 存储匹配模式
关于匹配(match)举个例子:
my $userinput="Guru99 Rocks";
if($userinput=~m/.*(Guru99).*/)
{
    print "Found Pattern";
}
else
{
    print "unable to find the pattern";
}
# Found Pattern

# 当然 =~ 可以替换成 !~  表示不匹配
关于替换(Substitution)举个例子:
my $a="Hello how are you";
$a=~s/hello/cello/gi;
print $a;
# 结果是:cello how are you
# 注意:g-globally, i-ignore case

Perl文件操作I/O

一个概念:文件句柄(FILEHANDLE,简称FH,可以理解成文件的代称) ,当打开文件进行读或写时使用

打开文件

利用open()函数:open(FILEHANDLE, "文件名或文件绝对路径");

既然打开了文件,那么接下来是要读还是要写? 具体操作像极了Linux

读 – open(my $fh,"<文件名或文件绝对路径"); 
写 – open(my $fh,">文件名或文件绝对路径");
追加 – open(my $fh,">>文件名或文件绝对路径");
练习读文件
open(FH,"<file.txt"); 
while(<FH>)   #对读入的每行执行一个循环操作
{
    print "$_";
}
close FH;
练习写文件
open(FH,">test.txt");
my $var=<>;
print FH $var;
close FH;
练习追加文件
open(FH,">>test.txt");
my $var=<>;
print FH $var;
close FH;
对文件夹处理
# 实现输出文件夹下的所有文件名
opendir(DIR,"C:\\Program Files\\"); # DIR是一个文件句柄

while(readdir(DIR)) # readdir是内置函数
{
   print "$_\n";
}
closedir(DIR); # 结束后要关闭文件句柄

Perl子函数

它和内置的perl函数(print、chmop等)差不多,只不过是我们自己在代码中定义的,确保了函数复用

一般格式:
sub subroutine_name 
{
    Statements…;    
}

知道了怎么定义一个子函数,那么如何调用它呢?
在子函数前面加上一个& 就可以实现,例如:

sub hash
{
my %hash=@_;
print %hash;
}
%value= ( 1=>'a', 2=>'b');
&hash(%value);
# 定义了一个叫hash的子函数,内容就是存储+输出。然后我们调用它就用的&hash
将参数传递给子函数
sub add
{
my $a=shift;
my $b=shift;
return($a+$b);
}
my $result=add(5,6);
print $result;
# 结果是11

Perl脚本标准

比较标准的格式:

#######################################################################
Program to read the file content
# Date: 22-2-2013
# Author : Guru99
########################################################################
#!/usr/bin/perl 
use strict;
use warnings; 
my $line;
open FR, "file.txt" || die("Cannot open the file $!");
while ($line=<FR>) 
{   
    print $line;
} # Looping file handler to print data

Perl模块

什么是模块?Module is a collection of reusable code, where we write subroutines in it.

标准的模块在perl安装时一起被装好了,有一些自定义的需要下载使用,一般以.pm结尾,用require调用


我的总结

这个题目应该是不假的,我自己看了6个多小时。理论上一天差不多可以理解性地看一遍perl基础,但是不要妄想看完这个就可以看别人写的脚本了,那中间还隔着自己练习、代码出错的一大步

学习感受
这次的学习感觉出知识迭代了。如果你之前没有接触过,可能真的需要一整天的时间来入门;如果之前零零散散接触过一些,再看一遍印象会增加一些


欢迎关注我们的公众号~_~  
我们是两个农转生信的小硕,打造生信星球,想让它成为一个不拽术语、通俗易懂的生信知识平台。需要帮助或提出意见请后台留言或发送邮件到jieandze1314@gmail.com

Welcome to our bioinfoplanet!
上一篇下一篇

猜你喜欢

热点阅读