习惯了了一些很好的IDE( 比如Matlab 很好的交互界面,VB有很好的图形化界面,还有R 与Rstidio,现在我基本都用JAVA的Eclipse),回过头来看一下Perl的编程环境,我们会发现这里没有很好的条件。但是这真的是这样的吗?
一开始我也很好奇,为什么Perl 就弄一个很好的IDE呢?这样会很方便我们进行调试啊,毕竟调试一个程序的时间占了我们绝大部分的时间。后来随着我对Perl的认识,对Linux的熟悉,我发现更本不需要这样:
计算机语言本身就像是一种我们自己的语言,那么我请问你在写文章的时候,你有什么调试的环节吗?(听起来可能很拗口)也就是说如果不用IDE进行边写程序边调试看那些变量的值的情况,很适合我们一气呵成,就像是我们在进行写作,IDE 只是一个辅助的工具。如果你想要真正地掌握好一门计算机语言,那么你不需要总是借助于一个IDE。
Larry 在发明Perl 之前是一个语言学家。对于语言有一定的研究,我们个人会感觉Perl 好像只能写不能看,但是其实这是很符合我们自然语言的。因为自然语言自己就缺乏很多的歧义性。对于一个听者来说这种
歧义性
其实相当于我们看别人活或者自己写程序时的那些感觉。所以我们可以注意一下自己编程序的方式,正如你自己说话要口齿清楚。学到这里你是否想过一个问题,你在和别人交流的时候。有一个隐含的原则,就是:尽量使用双方都知道的词汇避免使用一些特殊的词汇。 这样的话就可以很高效地进行沟通了。在我们的日常的生活中,我们其实就在使用一些我们大家都很熟悉的一般而又共通的词汇在进行着交流,不是吗?比如说,衣食住行这个我们大家都是共同深受的,所以这些东西是可以直接交流的。 同样在Perl中也一样,它里面也有一些内置的变量,这些内置的变量你就可以想象成一个我们都可能会用到的内置的变量。
对于Perl 没有一个很好的集成开发环境的话,perl还有一个很好的工具: 叫做Perl one line 这个Perl one line 可以很好地代替我们的一些函数学习以及脚本测试的工作。
Perl one line
夯实基础
首先明确 perl 的一个规则
- 在perl 里面双引号可以用
qq{}
qq##
还有qq()
代替 - 所以当然 用一个q 可以代替一个单引号
- 重要的一点:在windos 中要用 双引号+qq//来进行撰写;而在linux中是单引号+双引号
例子:
# on the windos
perl -e "print qq/Hello world\n/"
# one the linux
perl -e 'print "Hellow world" '
-e
-e
是执行单行命令的必选参数,它告诉perl 你现在执行的是单行命令。
-n
表示直接按行遍历文件:
perl -e "while (<>){ ... }"
# 等同于
perl -ne " . . . "
-p
表示按行处理文件,并在处理之后打印处理的结果
-a
表示按照空白分隔符分割行并存储结果到默认数组@F,一般与 -ne 一起用
perl -ane "print $F[2]"
-F
指定-a选项使用的分隔符,支持正则
perl -F'###' -ane '...'
-l
表示对所有输入的命令进行chomp,即去除\n;同时,对所有输出数据
自动附件\n
-i
启动原文编辑功能: 这一点可以代替sed 操作命令
#将原文件所有小写转换成大写
perl -i -pe 'tr/a-z/A-Z/'
# 按指定后缀备份原文件,并修改原文件
perl -i.bak -pe 'tr/a-z/A-Z/'
-0 【数值】
指定换行符记号($/变量),用8进制表示,默认为换行
-00 | 段落模式,即以连续换行为分隔符
-0777 | 禁用分隔符,一次读入整个文件
-0076 | 对应分隔符为'>',Fasta
-M
使用模块
Perl单行命令可以使用perl的模块,如使用sum函数的模块:
perl -MList::Util=sum -alne 'print sum @F'
BEGIN 和 END
Perl也可以像awk一样使用END命令,如打印出文件中总单词个数
perl -alne 'BEGIN{ print "start to run..."}; $t += @F; END { print $t}'
快速解决小问题
1.提取某个fasta的记录
perl -0076 -ane 'print qq{>$_} if $F[0] eq qq{gene_id}' out.fa
2.查看前10行
# 必须注意,几乎所有perl命令可以在任何操作系统切换,linux mac windows
perl -pe 'exit if $.>10'
3. 给定一个包含很多记录的csv文件,然后查看某一列的unique记录
可以直接用awk来实现
awk -F, '{print $3}' cog_metadata.csv |sort |uniq
下面用Perl
perl -F',' -lane ' $key = $F[2]; $myhash{$key} ++; END {print "$_ $myhash{$_}" for keys %myhash}' cog_metadata.csv
我们来用time
命令比较一下结果,输出结果如下:
$ time awk -F, '{print $3}' cog_metadata.csv |sort |uniq
UK-ENG
UK-NIR
UK-SCT
UK-WLS
adm1
awk -F, '{print $3}' cog_metadata.csv 5.65s user 0.04s system 99% cpu 5.702 total
sort 0.53s user 0.01s system 8% cpu 6.243 total
uniq 0.21s user 0.00s system 3% cpu 6.245 total
$ time perl -F',' -lane ' $key = $F[2]; $myhash{$key} ++; END {print "$_ $myhash{$_}" for keys %myhash}' cog_metadata.csv
UK-WLS 34913
UK-NIR 4514
UK-ENG 313799
UK-SCT 33946
adm1 1
perl -F',' -lane cog_metadata.csv 3.89s user 0.03s system 99% cpu 3.927 total