學(xué)習(xí)筆記 Perl語言概述
本文和大家重點(diǎn)討論一下Perl語言的相關(guān)內(nèi)容,用Perl語言寫的程序叫腳本(Perlscripts),而perl程序(perlprogram)通常是指名字叫做perl的程序,它是用來執(zhí)行腳本的。
Perl語言簡介
什么是Perl?
Perl是一個(gè)能用來完成大量不同任務(wù)的編程語言??梢杂脕斫忾_一個(gè)文件并打印一份報(bào)告,或者將一個(gè)文本文件轉(zhuǎn)換成另一種格式。Perl為相當(dāng)復(fù)雜的問題提供了一系列的工具,包括系統(tǒng)編程。
用Perl寫的程序叫腳本(Perlscripts),而perl程序(perlprogram)通常是指名字叫做perl的程序,它是用來執(zhí)行腳本的。
Perl是解釋型(不是編譯型)語言。這樣,運(yùn)行一個(gè)腳本,和運(yùn)行一個(gè)相應(yīng)的C程序來講,要花費(fèi)相當(dāng)多的CPU時(shí)間。但是,現(xiàn)在的計(jì)算機(jī)速度越來越快,寫一個(gè)C程序花的時(shí)間比寫一個(gè)Perl腳本多,從而總的來講,反而節(jié)省了你的時(shí)間。
Helloworld!
我們還是來寫一個(gè)Helloworld腳本。通過它來介紹Perl腳本的編寫和運(yùn)行的一些最基本的東西。
現(xiàn)在開始:
- [Jobs/]cat>;hello
- #!/usr/bin/perl
- print"Helloworld!\n";
- [Jobs/]chmoda+xhello
- [Jobs/]./hello
- Helloworld!
- [Jobs/]
注解:
1.用cat命令創(chuàng)建一個(gè)叫hello的文件,它包含一個(gè)很簡單的Perl腳本。通常可以用別的編輯器來創(chuàng)建腳本。
2.***行腳本是,#!/usr/bin/perl。它表示腳本是由perl程序來運(yùn)行的。它是一個(gè)必須的前綴。/usr/bin/perl部分是perl程序的路徑名。不同的安裝,路徑名是不同的。
3.隨后是相應(yīng)的Perl腳本,這里僅有一行。這一行是很好理解的,其中\(zhòng)n代表newline(換行)。在Perl的字符串,控制字符通常使用這種與C語言類似的表達(dá)法,\后跟一個(gè)字符。
4.程序?qū)懲曛?,用chmod命令讓這個(gè)包含腳本的程序可以執(zhí)行。在Linux里,文件創(chuàng)建是通常是不可執(zhí)行的,必須明確的改變文件的屬性。在這個(gè)命令中all用戶能execute(執(zhí)行)這個(gè)文件。
5.***,鍵入腳本文件名就能運(yùn)行這個(gè)腳本了。./表示是在Jobs目錄下的那個(gè)文件。
注意,在Perl中,和C語言一樣,一個(gè)語句是一個(gè)分號結(jié)尾的。#p#
數(shù)據(jù)結(jié)構(gòu)和變量
在Perl語言中一個(gè)變量的值可以是一個(gè)數(shù)字或字符串或其它別的東西。變量是沒有類型的。你可以將一個(gè)字符串賦給一個(gè)變量,以后,你可以將一個(gè)數(shù)字賦給同一個(gè)變量。
變量在使用前不需要申明。
試圖使用一個(gè)沒有初始化的變量,你用的實(shí)際上是0或者一個(gè)空的字符串或真假值中的false(假),具體是哪個(gè)值,由上下文決定。在使用命令行開關(guān)時(shí),表示要求Perl解釋器能給出告警信息,比如,-w報(bào)告使用了沒有定義的值。
Perlhasthreedatastructures:
Perl有三種數(shù)據(jù)結(jié)構(gòu):scalars,scalars數(shù)組,scalars聯(lián)合數(shù)組,就是"hashes"。
Scalar變量名通常以$符號開始,如$myvar。
數(shù)組通常以@符號開始,如@myarray。
Hashes的名字通常以%開始,如%myhash。
另外,子程序的名字以&開始,通常這個(gè)&可以省略。
上面的符號可以和英語中的單詞相對應(yīng):
$和the,
@和theseorthose,
%和theseorthose,
&和do。
名字是區(qū)分字母的大小寫的。比如$foo和$Foo是兩個(gè)不同的變量。
如果有個(gè)數(shù)組,如@myarr,你可以用方括號來索引它的某個(gè)成員。但此時(shí)@要變成$,如$myarr[5]。因?yàn)檫@個(gè)成員是一個(gè)scalar變量。
也可以組成一個(gè)數(shù)組,如@myvar[5..10],它是一個(gè)數(shù)組,是由@myvar組成的,它們的索引分別在5和10之間。
數(shù)組的索引是整數(shù),從0開始,和C語言一樣。
Hashes,能用字符串來索引它的成員,因此,索引方法不同。對于hashes,索引用大括號表示,如$myhash{'foobar'}。同樣,被索引的成員是scalar,必須用$開始。
每種變量都有他們自己的名字空間。因此$foo和@foo是不同的變量名。同樣$foo[1]是@foo的一部分,而不是$foo的一部分。另外,有兩個(gè)預(yù)定義的變量,$_和@_。必須知道$_[2]是@_中的一個(gè)成員。
一個(gè)數(shù)組事實(shí)上是一個(gè)值的列表。在Perl中,可以用以下方法來生成一個(gè)列表,(2,3,7,42)一個(gè)列表可以賦給一個(gè)數(shù)組變量,如@foo=(2,3,7,42);
列表在Perl中是很重要的,因?yàn)樵S多操作的結(jié)果是列表。
例子:顯示的行帶行號
下面的例子顯示scalar變量的使用。同時(shí)也介紹了Perl的幾個(gè)基本特征。
這個(gè)腳本打印出它的輸入,但輸出的每行有一個(gè)行號開始:
#!/usr/bin/perl
$line=1;
while(<>;){
print$line,"",$_;
$line=$line+1;}
Scalar變量$line是行記數(shù)。在一開始,它被初始化為1,在每次處理一行的循環(huán)中它的值加上一個(gè)1。
循環(huán)結(jié)構(gòu)的形式如下:
while(<>;){
處理一行輸入}
盡管看上去有點(diǎn)神秘,它確實(shí)非常便于使用。你不必關(guān)心真正的輸入操作;就用上面的結(jié)構(gòu)就可以了,用預(yù)定義的變量$_來引用輸入行。
print語句包含三個(gè)參數(shù),一個(gè)是打印行號,一個(gè)是打印一個(gè)空格,另一個(gè)是打印整個(gè)的輸入行。沒有打印換行,因?yàn)樽兞?_中已經(jīng)包含了換行符了。
實(shí)際上,可以將代碼寫的更加簡潔:
#!/usr/bin/perl
$line=1;
while(<>;){
print$line++,"",$_;}
這里,語句中包含了$line++而不僅僅是$line,因?yàn)樵赑erl中,和C語言類似,你可以通過給變量加一個(gè)運(yùn)算符來表示對一個(gè)變量加1操作。
如果希望行號是右對齊的,比如行號顯示在固定的5個(gè)字符這樣的區(qū)域內(nèi),左邊的用空格來填充。這相當(dāng)簡單,只需用下面這條語句代替print語句:
printf"%5d%s",$line++,$_;#p#
Perl語言腳本的輸入
Perl腳本從那里得到輸入值?默認(rèn)的,即在輸入沒有任何參數(shù)的情況下,輸入來自Linux中所謂的輸入流。通常是用戶的鍵盤。
通常希望腳本從文件中輸入。簡單的將文件名作為命令行參數(shù),也就是,腳本文件的名字是命令的時(shí)候。這樣,舉個(gè)例子,如果你已經(jīng)寫好了這個(gè)簡單的腳本,并命名為lines,你可以用下面的方法來測試:
[Jobs/]./lineslines
1#!/usr/bin/perl
2$line=1;
3while(<>;){
4print$line++,"",$_;}
[Jobs/]
你可能寫了幾個(gè)文件名字作為命令行參數(shù),比如:linesfoobarzap
這意味著腳本lines將文件foo,bar,和zap作為一個(gè)已經(jīng)合并的單個(gè)文件來處理。
例子:拆分輸入行
在Perl中,你可以不用詳細(xì)地寫代碼就能將數(shù)據(jù)分成幾個(gè)域。只需指定你想做什么。
比如,語句:
split;
首先將當(dāng)前輸入行分解成有空格分隔的域,然后將這些域分別賦值給預(yù)定義數(shù)組@_。隨后,就可以使用索引來存取這些域。變量$#_包含域的數(shù)目:它的值是域的數(shù)目減1。
假設(shè),舉個(gè)例子,有一些數(shù)據(jù),每行包括幾個(gè)由空格分隔的項(xiàng),如果寫一個(gè)Perl腳本,將每行的第二項(xiàng)挑選出來??梢詫懴旅孢@樣的一個(gè)腳本來實(shí)現(xiàn)。
#!/usr/bin/perl
while(<>;){
split;
print$_[1],"\n";}
要注意的是由于在Perl中索引值從0開始,因此用一個(gè)值為1的索引是引用第二個(gè)域。
Perl語言的控制結(jié)構(gòu)
Perl有豐富的控制結(jié)構(gòu)。理論上,通常也很實(shí)際,可以用if語句來實(shí)現(xiàn)分支結(jié)構(gòu),while語句來實(shí)現(xiàn)循環(huán)結(jié)構(gòu)。
在控制結(jié)構(gòu)中,實(shí)現(xiàn)有條件執(zhí)行的動(dòng)作,或循環(huán)執(zhí)行的動(dòng)作做為blocks。一個(gè)塊是一個(gè)有大括號圍起來的一系列語句。注意,括號是必須的,這和C語言略有不同。
最簡單的if語句的格式是:if(expression)block
它表示,先計(jì)算表達(dá)式的值,如果表達(dá)式的結(jié)果為真的話,就執(zhí)行塊語句。
比如,語句if($i<10){$j=100;},如果$i的值小于10的話,$j的值就設(shè)為100。
一個(gè)有兩個(gè)分支的語句的格式如下:
if(expression)block1elseblock2
首先計(jì)算表達(dá)式的值,如果為真,執(zhí)行block1,否則執(zhí)行block2。
while語句的格式如下:
while(expression)block
先計(jì)算表達(dá)式的值,如果為真,執(zhí)行塊里面的語句,然后,再計(jì)算表達(dá)式的值,直到表達(dá)式的值為假,否則,還要執(zhí)行塊里的語句。
下面的腳本是一個(gè)使用while語句的簡單例子,它將輸入行進(jìn)行分解,按相反的方向把各個(gè)域打印出來。
#!/usr/bin/perl
while(<>;){
split;
$i=$#_;
while($i>;=0){
print$_[$i--],"";}
print"\n";
}
在內(nèi)部的while循環(huán),控制是建立在使用一個(gè)輔助的變量$i上的。它的值初始化成對***一個(gè)域的引用,并且不斷遞減,直到為0,此時(shí),所有的域都處理完畢。運(yùn)算符>;=的意思是大于或等于。
字符串處理
Perl語言有強(qiáng)大的字符串處理工具。比如,通常希望將輸入數(shù)據(jù)轉(zhuǎn)換成小寫,很簡單:
tr/A-Z/a-z/;
這可以理解成:將范圍是A到Z的所有字符轉(zhuǎn)換(translate)成范圍是a到z的字符。
這個(gè)操作是在變量$_上,也就是當(dāng)前輸入行上進(jìn)行的。如果你想將它用到變量$foo上,你必須這樣寫:
$foo=~tr/A-Z/a-z/;
有可能這樣的表達(dá)式很怪,但一旦熟悉之后,Perl的字符串工具很容易使用。
例子:文件重命名
Linux用戶需要將以后綴,比如.for結(jié)尾的文件的名字都重新命名成另一個(gè)后綴,比如.f。通常沒有直接的命令來完成這一個(gè)任務(wù)。如果你想要用mv*.for*.f,通常這樣并不能解決問題。
但可以用Perl來寫一個(gè)簡單的腳本來實(shí)現(xiàn):
#!/usr/bin/perl
while(<*.for>;){
$oldname=$_;
s/\.for$/\.f/;
rename$oldname,$_;
}
while語句表示它只對*.for的名字進(jìn)行處理。首先將找到的要處理的文件名,把匹配的文件名賦給$_變量。
在循環(huán)體內(nèi),首先將$_變量所指的文件名保存到變量$oldname里。隨后,對它進(jìn)行替換。
***,用替換好的名字來重命名文件。rename是Perl的一個(gè)內(nèi)建函數(shù),他有兩個(gè)參數(shù)。我們可以用另一條語句來代替它:
system"mv$oldname$_";
它是通過調(diào)用操作系統(tǒng)命令來實(shí)現(xiàn)的。
另外,需要注意的是語句s/\.for$/\.f/;中的兩個(gè)\。如果該語句中沒有\(zhòng),則成為:
s/.for$/.f/;
這個(gè)語句就不對了。如果遇到zapfor.for,就會(huì)產(chǎn)生如下替換:za.f.for。因?yàn)榉?代表任意字符。所以.for的意思是只要在字符串中包含for,就做替換。因此會(huì)產(chǎn)生上述結(jié)果。為了表示.,就必須用到換碼序列,用\.來表示符號.。這與C語言中的概念類似。
小結(jié)
Perl語言的語法和C語言有些相同之處,比如控制結(jié)構(gòu),語句的;結(jié)尾,換碼序列等等。但它們也有明顯差別。C語言是編譯型的,C程序的運(yùn)行效率高。Perl語言是解釋型的,腳本的運(yùn)行效率比較低。但是Perl語言的綜合性較高,編寫一些功能較復(fù)雜的程序所化的時(shí)間比較短。另外,Perl的變量是沒有數(shù)據(jù)類型。
【編輯推薦】