簡體   English   中英

在Perl中逐行讀取文件

[英]Reading a file line by line in Perl

我想一行讀取一個文件,但它只讀取第一行。 如何閱讀所有行?

我的代碼:

open(file_E, $file_E);

while ( <file_E> ) {
    /([^\n]*)/;
    print $line1;
}

close($file_E);

讓我們從查看代碼開始。

open(file_E, $file_E);

while ( <file_E> ) {
    /([^\n]*)/;
    print $line1;
}

close($file_E);

在第一行,使用裸file_E打開一個名為$file_E的文件。 只要文件成功打開,它就應該起作用。 這將是更好地還檢查這兩種操作方式之一的成功:要么把use autodie; 在腳本的頂部(但要冒風險在其代碼與此級別的錯誤處理不兼容的地方應用其語義),或將open更改為如下所示:

open(file_E, $file_E) or die "Failed to open $file_E: $!\n";

現在,如果您無法打開文件,您將收到一條錯誤消息,可以幫助您查找問題。

接下來,讓我們看看while循環,因為在這里,您遇到的問題會導致您遇到錯誤。 while循環的第一行,您有以下內容:

while ( <file_E> ) {

通過咨詢perldoc perlsyn您將看到該行在實際情況中是特殊情況:

while (defined($_ = <file_E>)) {

因此,您的代碼在連續的迭代中隱式地將每行分配給$_ 此外,通過咨詢perldoc perlop您會發現,在調用匹配運算符( /.../m/.../ )而未使用=~顯式綁定匹配時,匹配將與$_綁定。 到目前為止,到目前為止還算不錯。 但是,您實際上並沒有對比賽做任何有用的事情。 匹配運算符將返回布爾真/假,以判斷匹配是否成功。 並且由於您的模式包含捕獲括號,因此它將捕獲捕獲變量$1 但是,您永遠不會測試比賽成功,也不會再提$1

在接下來的行中,執行以下操作: print $line1 $line1在您的代碼中的哪個位置分配了值? 因為從不向您顯示的內容分配任何值。

我只能猜測,您的意圖是遍歷文件的各行,捕獲該行但不包含尾隨的換行符,然后進行打印。 看來您希望不帶任何換行符來打印它,以便所有輸入文件都被打印為一行輸出。

open my $input_fh_e, '<', $file_E or die "Failed to open $file_E: $!\n";

while(my $line = <$input_fh_e>) {
    chomp $line;
    print $line;
}

close $input_fh_e or die "Failed to close $file_E: $!\n";

無需捕獲任何內容-如果捕獲所做的只是將所有內容抓到換行符,則可以簡單地用chomp剝離換行符。

在我的示例中,我使用了詞法文件句柄(用my聲明的詞法范圍的文件句柄)。 在現代Perl中,這通常是更好的做法,因為它避免使用裸字,避免可能的命名空間沖突,並確保在詞法作用域關閉后立即關閉句柄。

我還使用了open的“三個arg”版本,它比較安全,因為它消除了$file_E用於打開管道或執行其他某些惡意或簡單的意外shell操作的可能性。

我建議也use strict;啟動腳本use strict; ,因為這樣做了,您在編譯時會收到一條錯誤消息,告訴您從未聲明$line1 另外,還應use warnings啟動腳本,以便在嘗試為$line1分配值之前打印此警告。

代碼中的大多數問題將在perldoc perlintro進行討論,假設您已經安裝了Perl,只需鍵入perldoc perlintro即可perldoc perlintro 通讀perlintro通常需要20-40分鍾。 如果有文檔構成開始編寫Perl代碼之前的必讀內容,則該閱讀內容可能包括perlintro

另一種選擇是,注意$ _將包括換行符,因此,如果您不希望在$ line中換行符,則需要將其砍掉:

open(file_E, $file_E);

while ( <file_E> ) {
    my $line = $_;
    print $line;
}

close($file_E);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM