簡體   English   中英

如何將文件內容讀入Perl標量?

[英]How do I read a file's contents into a Perl scalar?

我想做的是從另一台服務器獲取文件的內容。 由於即時消息與perl不協調,因此我也不知道其mod和功能是這樣的:

 my $fileContents;
 if( $md5Con =~ m/\.php$/g ) {
     my $ftp = Net::FTP->new($DB_ftpserver, Debug => 0) or die "Cannot connect to some.host.name: $@";
     $ftp->login($DB_ftpuser, $DB_ftppass) or die "Cannot login ", $ftp->message;
     $ftp->get("/" . $root . $webpage, "c:/perlscripts/" . md5_hex($md5Con) . "-code.php") or die $ftp->message;
     open FILE, ">>c:/perlscripts/" . md5_hex($md5Con) . "-code.php" or die $!;
     $fileContents = <FILE>;
     close(FILE);
     unlink("c:/perlscripts/" . md5_hex($md5Con) . "-code.php");
     $ftp->quit;
 }

我認為id要做的是從服務器獲取文件,放在本地計算機上,編輯內容,上傳到任何地方,然后刪除臨時文件。

但是我似乎無法弄清楚如何獲取文件的內容。

open FILE, ">>c:/perlscripts/" . md5_hex($md5Con) . "-code.php" or die $!;
$fileContents = <FILE>;
close(FILE);

不斷出錯;

使用未初始化的值$ fileContents

我猜這意味着它沒有返回值。

任何幫助,不勝感激。

>>>>>>>>>>編輯<<<<<<<<<<

my $fileContents;
if( $md5Con =~ m/\.php$/g ) {
    my $ftp = Net::FTP->new($DB_ftpserver, Debug => 0) or die "Cannot connect to some.host.name: $@";
    $ftp->login($DB_ftpuser, $DB_ftppass) or die "Cannot login ", $ftp->message;
    $ftp->get("/" . $root . $webpage, "c:/perlscripts/" . md5_hex($md5Con) . "-code.php") or die $ftp->message;
    my $file = "c:/perlscripts/" . md5_hex($md5Con) . "-code.php";
    {
        local( $/ ); # undefine the record seperator
        open FILE, "<", $file or die "Cannot open:$!\n";
        my $fileContents = <FILE>;
        #print $fileContents;
        my $bodyContents;
        my $headContents;

        if( $fileContents =~ m/<\s*body[^>]*>.*$/gi ) {
            print $0 . $1 . "\n";
            $bodyContents = $dbh->quote($1);    
        }
        if( $fileContents =~ m/^.*<\/head>/gi ) {
            print $0 . $1 . "\n";
            $headContents = $dbh->quote($1);    
        }

        $bodyTable = $dbh->quote($bodyTable);
        $headerTable = $dbh->quote($headerTable);
        $dbh->do($createBodyTable) or die " error: Couldn't create body table: " . DBI->errstr;
        $dbh->do($createHeadTable) or die " error: Couldn't create header table: " . DBI->errstr;
        $dbh->do("INSERT INTO $headerTable ( headData, headDataOutput ) VALUES ( $headContents, $headContents )") or die " error: Couldn't connect to database: " . DBI->errstr;
        $dbh->do("INSERT INTO $bodyTable ( bodyData, bodyDataOutput ) VALUES ( $bodyContents, $bodyContents )") or die " error: Couldn't connect to database: " . DBI->errstr;
        $dbh->do("INSERT INTO page_names (linkFromRoot, linkTrue, page_name, table_name, navigation, location) VALUES ( $linkFromRoot, $linkTrue, $page_name, $table_name, $navigation, $location )") or die " error: Couldn't connect to database: " . DBI->errstr;

        unlink("c:/perlscripts/" . md5_hex($md5Con) . "-code.php");
    }
    $ftp->quit;
}

上面使用print將打印整個文件。 但是,由於某些原因,兩個常規表達式都返回false。 知道為什么嗎?

if( $fileContents =~ m/<\s*body[^>]*>.*$/gi ) {
            print $0 . $1 . "\n";
            $bodyContents = $dbh->quote($1);    
        }
        if( $fileContents =~ m/^.*<\/head>/gi ) {
            print $0 . $1 . "\n";
            $headContents = $dbh->quote($1);    
        }

標准發行版隨附的Perl常見問題解答的第5節對此進行了介紹

如何一次讀取整個文件?

您可以使用Path::Class::File::slurp模塊一步完成。

use Path::Class;
$all_of_it = file($filename)->slurp; # entire file in scalar
@all_lines = file($filename)->slurp; # one line per element

Perl慣用的處理文件中所有行的方法是一次執行一行:

open (INPUT, $file) || die "can't open $file: $!";
while (<INPUT>) {
    chomp;
    # do something with $_
}
close(INPUT)        || die "can't close $file: $!";

這比將整個文件作為一行行讀取到內存中,然后一次處理一個元素要有效得多,這通常是(即使並非總是如此)錯誤的方法。 每當您看到有人這樣做時:

@lines = <INPUT>;

您應該認真思考為什么需要一次加載所有內容。 這不是一個可擴展的解決方案。 您可能還會發現使用標准的Tie::File模塊或DB_File模塊的$DB_RECNO綁定會更有趣,這允許您將數組綁定到文件,以便訪問數組中的元素實際上是訪問文件中的相應行。 。

您可以將整個文件句柄內容讀入標量。

{
local(*INPUT, $/);
open (INPUT, $file) || die "can't open $file: $!";
$var = <INPUT>;
}

這會暫時取消記錄分隔符的定義,並將在塊退出時自動關閉文件。 如果文件已經打開,請使用以下命令:

$var = do { local $/; <INPUT> };

對於普通文件,您還可以使用read功能。

read( INPUT, $var, -s INPUT );

第三個參數測試INPUT文件句柄上數據的字節大小,並將那么多字節讀取到緩沖區$var

如果要一次性讀取所有文件內容,請使用Path :: Class :: File :: slurp

但是,更重要的是,使用HTML解析器來解析HTML。

open FILE, "c:/perlscripts" . md5_hex($md5Con) . "-code.php" or die $!;
while (<FILE>) {
    # each line is in $_
}
close(FILE);

將打開文件,並允許您逐行處理它(如果這是您想要的-否則請調查binmode )。 我認為問題出在您的文件名以>>開頭。 有關更多信息,請參見本教程

我注意到您還使用正則表達式來解析HTML。 通常,我建議使用解析器來執行此操作(例如,參見HTML :: Parser )。 由於HTML缺乏正則性,因此正則表達式不適合HTML,並且在一般情況下不能可靠地工作。

另外,如果您需要編輯文件的內容,請查看CPAN模塊Tie :: File
該模塊使您無需創建用於編輯內容並將其寫回到同一文件的臨時文件。

編輯
您正在查看的是一種處理文件的方法。 可能是您必須取消定義記錄分隔符$/

下面的代碼對我來說很好用:

 use strict; my $file = "test.txt"; { local( $/ ); # undefine the record seperator open FILE, "<", $file or die "Cannot open:$!\\n"; my $lines =<FILE>; print $lines; } 

另請參閱本部分中的“傳統咕嘟咕嘟” 的文章

但是,由於某些原因,兩個常規表達式都返回false。 知道為什么嗎?

. 默認情況下,正則表達式中的匹配除換行符外的任何字符。 大概在</head>標記之前和<body>標記之后都有換行符。 . 匹配任何字符,包括換行符,請使用//s標志。

我不確定您的print $0 . $1 ...是多少print $0 . $1 ... print $0 . $1 ...代碼是關於; 您不會在匹配中捕獲要存儲在$ 1中的任何內容,並且$ 0並不是用於正則表達式捕獲的變量,這是非常不同的。

如果要獲取文件的內容,

 @lines = <FILE>;

使用File::Slurp::Tiny File::Slurp一樣方便,但是沒有bug

暫無
暫無

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

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