習(xí)慣了了一些很好的IDE( 比如Matlab 很好的交互界面继阻,VB有很好的圖形化界面示括,還有R 與Rstidio姆怪,現(xiàn)在我基本都用JAVA的Eclipse)溯乒,回過頭來看一下Perl的編程環(huán)境杯道,我們會發(fā)現(xiàn)這里沒有很好的條件匪煌。但是這真的是這樣的嗎?
一開始我也很好奇蕉饼,為什么Perl 就弄一個很好的IDE呢虐杯?這樣會很方便我們進(jìn)行調(diào)試啊,畢竟調(diào)試一個程序的時間占了我們絕大部分的時間昧港。后來隨著我對Perl的認(rèn)識擎椰,對Linux的熟悉,我發(fā)現(xiàn)更本不需要這樣:
計(jì)算機(jī)語言本身就像是一種我們自己的語言创肥,那么我請問你在寫文章的時候达舒,你有什么調(diào)試的環(huán)節(jié)嗎值朋?(聽起來可能很拗口)也就是說如果不用IDE進(jìn)行邊寫程序邊調(diào)試看那些變量的值的情況,很適合我們一氣呵成巩搏,就像是我們在進(jìn)行寫作昨登,IDE 只是一個輔助的工具。如果你想要真正地掌握好一門計(jì)算機(jī)語言贯底,那么你不需要總是借助于一個IDE丰辣。
Larry 在發(fā)明Perl 之前是一個語言學(xué)家。對于語言有一定的研究禽捆,我們個人會感覺Perl 好像只能寫不能看笙什,但是其實(shí)這是很符合我們自然語言的。因?yàn)樽匀徽Z言自己就缺乏很多的歧義性胚想。對于一個聽者來說這種
歧義性
其實(shí)相當(dāng)于我們看別人活或者自己寫程序時的那些感覺琐凭。所以我們可以注意一下自己編程序的方式,正如你自己說話要口齒清楚浊服。學(xué)到這里你是否想過一個問題统屈,你在和別人交流的時候。有一個隱含的原則牙躺,就是:盡量使用雙方都知道的詞匯避免使用一些特殊的詞匯愁憔。 這樣的話就可以很高效地進(jìn)行溝通了。在我們的日常的生活中孽拷,我們其實(shí)就在使用一些我們大家都很熟悉的一般而又共通的詞匯在進(jìn)行著交流惩淳,不是嗎?比如說乓搬,衣食住行這個我們大家都是共同深受的,所以這些東西是可以直接交流的代虾。 同樣在Perl中也一樣进肯,它里面也有一些內(nèi)置的變量,這些內(nèi)置的變量你就可以想象成一個我們都可能會用到的內(nèi)置的變量棉磨。
對于Perl 沒有一個很好的集成開發(fā)環(huán)境的話江掩,perl還有一個很好的工具: 叫做Perl one line 這個Perl one line 可以很好地代替我們的一些函數(shù)學(xué)習(xí)以及腳本測試的工作。
Perl one line
夯實(shí)基礎(chǔ)
首先明確 perl 的一個規(guī)則
- 在perl 里面雙引號可以用
qq{}
qq##
還有qq()
代替 - 所以當(dāng)然 用一個q 可以代替一個單引號
- 重要的一點(diǎn):在windos 中要用 雙引號+qq//來進(jìn)行撰寫乘瓤;而在linux中是單引號+雙引號
例子:
# on the windos
perl -e "print qq/Hello world\n/"
# one the linux
perl -e 'print "Hellow world" '
-e
-e
是執(zhí)行單行命令的必選參數(shù)环形,它告訴perl 你現(xiàn)在執(zhí)行的是單行命令。
-n
表示直接按行遍歷文件:
perl -e "while (<>){ ... }"
# 等同于
perl -ne " . . . "
-p
表示按行處理文件衙傀,并在處理之后打印處理的結(jié)果
-a
表示按照空白分隔符分割行并存儲結(jié)果到默認(rèn)數(shù)組@F抬吟,一般與 -ne 一起用
perl -ane "print $F[2]"
-F
指定-a選項(xiàng)使用的分隔符,支持正則
perl -F'###' -ane '...'
-l
表示對所有輸入的命令進(jìn)行chomp,即去除\n;同時统抬,對所有輸出數(shù)據(jù)
自動附件\n
-i
啟動原文編輯功能: 這一點(diǎn)可以代替sed 操作命令
#將原文件所有小寫轉(zhuǎn)換成大寫
perl -i -pe 'tr/a-z/A-Z/'
# 按指定后綴備份原文件火本,并修改原文件
perl -i.bak -pe 'tr/a-z/A-Z/'
-0 【數(shù)值】
指定換行符記號($/變量)危队,用8進(jìn)制表示,默認(rèn)為換行
-00 | 段落模式钙畔,即以連續(xù)換行為分隔符
-0777 | 禁用分隔符茫陆,一次讀入整個文件
-0076 | 對應(yīng)分隔符為'>',F(xiàn)asta
-M
使用模塊
Perl單行命令可以使用perl的模塊擎析,如使用sum函數(shù)的模塊:
perl -MList::Util=sum -alne 'print sum @F'
BEGIN 和 END
Perl也可以像awk一樣使用END命令簿盅,如打印出文件中總單詞個數(shù)
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命令可以在任何操作系統(tǒng)切換揍魂,linux mac windows
perl -pe 'exit if $.>10'
3. 給定一個包含很多記錄的csv文件桨醋,然后查看某一列的unique記錄
可以直接用awk來實(shí)現(xiàn)
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
命令比較一下結(jié)果,輸出結(jié)果如下:
$ 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