0

私がやろうとしているのは、別のサーバーからファイルの内容を取得することです。私は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;
 }

私が考えたのは、サーバーからファイルを取得し、ローカルマシンに置き、コンテンツを編集し、どこにでもアップロードしてから一時ファイルを削除することです。

しかし、ファイルの内容を取得する方法がわかりません。

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 を使用すると、ファイル全体が印刷されます。しかし、何らかの理由で、2 つの正規表現が 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);    
        }
4

7 に答える 7

10

これは、標準ディストリビューションに含まれるPerl FAQ のセクション 5 で説明されています。

ファイル全体を一度に読み込むにはどうすればよいですか?

Path::Class::File::slurpモジュールを使用して、1 つのステップでそれを行うことができます。

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

ファイル内のすべての行を処理する慣習的な Perl のアプローチは、一度に 1 行ずつ処理することです。

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

これは、ファイル全体を行の配列としてメモリに読み込み、一度に 1 つの要素を処理するよりもはるかに効率的です。誰かがこれをしているのを見たときはいつでも:

@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 );

INPUT3 番目の引数は、ファイルハンドルのデータのバイトサイズをテストし、そのバイト数をバッファに読み込み$varます。

于 2010-02-06T19:44:06.427 に答える
8

すべてのファイルの内容を一度に読み取りたい場合は、Path::Class::File::slurpを使用します。

ただし、より重要なことは、HTML パーサーを使用して HTMLを解析することです。

于 2010-02-06T19:21:06.580 に答える
3
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 には適しておらず、一般的なケースでは確実に機能しません。

于 2010-02-06T14:56:30.490 に答える
2

また、ファイルの内容を編集する必要がある場合は、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;
}

この記事 の「伝統的な丸呑み」のセクションも参照してください。

于 2010-02-06T15:03:42.597 に答える
1

しかし、何らかの理由で、2つの通常の式がfalseを返しています。なぜですか?

.正規表現では、デフォルトで改行以外のすべての文字に一致します。おそらく、タグの前と</head>タグの後に改行があります<body>.改行を含むすべての文字を一致させるには、//sフラグを使用します。

あなたのprint $0 . $1 ...コードが何であるかわかりません。$ 1に格納される一致で何もキャプチャしていません。また、$ 0は正規表現のキャプチャに使用される変数ではなく、非常に異なります。

于 2010-02-07T09:40:46.290 に答える
0

ファイルの内容を取得したい場合は、

 @lines = <FILE>;
于 2010-02-06T15:15:07.517 に答える
0

を使用しFile::Slurp::Tinyます。と同じくらい便利ですが、バグFile::Slurpはありません。

于 2014-08-16T11:18:26.633 に答える