溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

《Perl語言入門》之四——輸入與輸出

發(fā)布時間:2020-08-19 21:44:02 來源:網(wǎng)絡(luò) 閱讀:1701 作者:kunder 欄目:系統(tǒng)運維

標準輸入輸出

STDIN可以用于接收鍵盤輸入或是文件輸入。在標量上下文中執(zhí)行該操作時,會返回輸入中的下一行。

while <STDIN> {
    chomp;
    print "I saw $_";
}
foreach <STDIN> {
    chomp;
    print;
}

看起來上例中的“while”循環(huán)和“foreach”的行為完全一樣,其實是有些差別的——在while循環(huán)里,Per會讀取一行輸入,把它存入某個變量并且執(zhí)行循環(huán)的主體,接下來它會回去尋找其他輸入行;foreach循環(huán)中,行輸入操作符會在列表上下文中執(zhí)行(因為foreach需要逐項處理列表內(nèi)容),因此Perl會將全部內(nèi)容讀入內(nèi)存,然后才開始執(zhí)行循環(huán)。當需要處理的輸入數(shù)據(jù)長度很大時,比如處理400M大小的Web服務(wù)器日志文件,foreach的效率會比while低很多。因此最好的做法是盡量使用while循環(huán),讓它每次處理一行。


鉆石操作符的輸入<>

鉆石操作符提供類似 標準Unix工具程序的參數(shù)輸入方式,例如對于如下Perl程序“my_program”:

while <> {
    chomp;
    print;
}

如果執(zhí)行命令“./my_program fred barney betty”,它應(yīng)該會處理文件fred,接著是barney,最后是betty。(鉆石操作符怎么會知道檢查命令行參數(shù)呢?其實它的參數(shù)是來自@ARGV數(shù)組)

如果執(zhí)行命令是沒有指定調(diào)用參數(shù),程序會從標準輸入流采集數(shù)據(jù)。

當然還有個例外,如果參數(shù)中包含連字符“-”,則Perl代碼處理到連字符時,會臨時改從標準輸入讀取數(shù)據(jù)。


使用print/printf/say輸出到標準輸出

Print操作符會讀取后續(xù)列表中的所有元素,并把每一項一次送到標準輸出。

print <>; #相當于Unix下的cat命令 
print sort <>; #相當于Unix下的sort命令

如果對print的輸出格式不夠滿意,還可以使用printf來產(chǎn)生格式化過的輸出結(jié)果。

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

當然Perl一如既往地提供了更方便的格式"%g" (你可以把"g"當成"General"數(shù)字轉(zhuǎn)換)。

一般來說,我們編寫printf的格式化字符串時已經(jīng)確定了替換參數(shù)的個數(shù)和類型,不過萬事沒有絕對,下面的例子就是用程序在運行時動態(tài)產(chǎn)生格式字符串。

my @items = qw( wilma dino pebbles ); 
my $format = "The items are: \n" . ("%10s\n" x @items); 
printf $format, @items;

另外,有個叫Perl Power Tools (PPT)的項目目標就是用perl重寫所有經(jīng)典Unix工具程序,但是在重寫shell的時候陷入了難題。PPT項目一度非常有用,因為它使所有便準的工具程序可以運行在非Unix機器上。

Say函數(shù)的功能和print的差不多,但在打印每行內(nèi)容時都會自動加上換行符。所以下面幾種寫法的輸出結(jié)果都一樣:

use 5.010 
print "Hello!\n"; 
print "Hello!" . "\n"; 
say "Hello!";


文件句柄

一般使用全大寫字母來命名文件句柄,但是有6個個數(shù)文件句柄是Perl保留的——STDIN、STDOUT、STDERR、DATA、ARGV以及ARGVOUT。

open CONFIG, 'dino'; #打開一個文件 
open CONFIG, '<dino' #只讀方式打開一個文件 
open REDROCK, '>fred' #創(chuàng)建一個新的文件,如果已經(jīng)存在,則清除原有內(nèi)容并以新內(nèi)容代替 
open LOG, '>>logfile' #追加方式打開一個文件,如果文件不存在,則創(chuàng)建一個新文件

5.6版的Perl里,加入了open的三個參數(shù)的寫法:

open CONFIG, '<', 'dono'; 
open BEDROCK, '>', $file_name; 
                                                                         
open CONFG, '<:encoding(UTF-8)', $file_name; #使用UTF-8編碼打開文件,這種書寫方式會確認編碼是否正確 
open BEDROCK, '>:utf8', &logfile_name(); #這種簡寫的方式不會考慮輸入輸出的數(shù)據(jù)是否真的是合法的UTF-8字符串

我們可以通過下面的這條命令打印出說有perl能理解的字符編碼清單:

% perl -MEncode -le "print for Encode->encodings(':all')"

除了字符編碼之外,數(shù)據(jù)輸入或輸出過程中還可以做其他轉(zhuǎn)換操作。比如DOS風(fēng)格和Unix風(fēng)格的換行符:

open BEDROCK, '>:crlf', $file_name; #按照DOS換行符風(fēng)格寫入文件 
open BEDROCK, '<:crlf', $file_name; #讀取DOS風(fēng)格的文件



關(guān)閉文件句柄

close BEDROCK;


出錯處理

當Perl遇到致命錯誤時,你的程序應(yīng)該立刻中止運行,并發(fā)出錯誤信息告知原因。這樣的功能可以用die函數(shù)來實現(xiàn)。

if ( ! open LOG, '>>', 'logfile' ) { 
    die "Cannot create logfile: $!"; #die函數(shù)會終止程序的運行并打印出錯信息 
}

"$!"代表可讀的系統(tǒng)錯誤信息。一般來說,當系統(tǒng)拒絕我們的請求時,"$!"會給出一個解釋,類似于C語言中調(diào)用perror取得的字符串。

如果Perl遇到的錯誤是非致命的,可以使用warn函數(shù)送出警告信息。warn函數(shù)的功能就是產(chǎn)生類似于Perl的內(nèi)置警告信息的信息(比如啟用警告信息時,使用某個undef變量卻將它當成已有的值來參與計算,就會觸發(fā)警告信息)。


自動檢測致命錯誤

從Perl 5.10開始,為人稱道的autodie編譯指令已經(jīng)成為標準庫的一部分。

use autodie;

這條編譯指令是靠判別具體操作的類型來工作的。如果Perl內(nèi)置函數(shù)調(diào)用了操作系統(tǒng)接口的話,那么中途出現(xiàn)的錯誤并不是編程人員所能控制的,所以一旦發(fā)現(xiàn)系統(tǒng)調(diào)用出錯,autodie便會自動幫你調(diào)用die。


使用文件句柄

以寫入或添加方式打開文件后,可以直接使用print或printf將字符串輸出到文件中:

print LOG "Captain's log, stardate 3.14159"; 
printf STDERR "%d percent complete.\n", $done/$total * 100;

如果print/printf的參數(shù)列表沒有提供文件句柄,則字符串默認被輸出到STDOUT。不過可以使用select操作符改變默認的文件句柄,另外還有一個很奇特的變量"$|",當它的值被設(shè)為1,就會使當前的默認句柄在每次輸出操作后立刻刷新緩沖區(qū)。所以,如果要讓輸出的內(nèi)容立即顯示(比如在讀取監(jiān)視某個耗時程序的實時日志時),應(yīng)該這么做:

select LOG; # 將默認輸出設(shè)定為LOG文件句柄 
$|= 1; # 不要將LOG的內(nèi)容保留在緩沖區(qū) 
select STDOUT; 
print LOG "This gets written to the LOG at once!\n";


向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI