[string] Perl에서 전체 파일을 문자열로 어떻게 읽을 수 있습니까?

.html 파일을 하나의 큰 긴 문자열로 열려고합니다. 이것이 내가 가진 것입니다.

open(FILE, 'index.html') or die "Can't read file 'filename' [$!]\n";
$document = <FILE>;
close (FILE);
print $document;

결과 :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN

그러나 결과는 다음과 같습니다.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

이렇게하면 전체 문서를 더 쉽게 검색 할 수 있습니다.



답변

더하다:

 local $/;

파일 핸들에서 읽기 전에. 전체 파일을 한 번에 읽을 수있는 방법을 참조하십시오 . , 또는

$ perldoc -q "전체 파일"

참조 파일 핸들과 관련된 변수perldoc perlvarperldoc -f local.

덧붙여서, 스크립트를 서버에 넣을 수 있다면 원하는 모든 모듈을 가질 수 있습니다. 내 모듈 / 라이브러리 디렉토리를 유지하는 방법을 참조하십시오 . .

또한, 경로 :: 클래스 :: 파일은 당신이 할 수 후루룩 소리 내며 먹기토 해낸다 .

Path :: Tinyslurp, slurp_rawslurp_utf8 그에 spew상응하는 것과 같은 훨씬 더 편리한 방법을 제공합니다 .


답변

나는 다음과 같이 할 것입니다.

my $file = "index.html";
my $document = do {
    local $/ = undef;
    open my $fh, "<", $file
        or die "could not open $file: $!";
    <$fh>;
};

open의 3 개 인수 버전 사용에 유의하십시오. 이전의 2 개 (또는 1 개) 인수 버전보다 훨씬 안전합니다. 또한 어휘 파일 핸들의 사용에 유의하십시오. 어휘 파일 핸들은 여러 가지 이유로 오래된 베어 워드 변형보다 더 좋습니다. 여기에서 그중 하나를 활용하고 있습니다. 범위를 벗어나면 닫힙니다.


답변

파일 :: 소리내어 먹는다 :

use File::Slurp;
my $text = read_file('index.html');

예, CPAN을 사용할 수도 있습니다 .


답변

모든 게시물은 약간 비관 상적입니다. 관용구는 다음과 같습니다.

open my $fh, '<', $filename or die "error opening $filename: $!";
my $data = do { local $/; <$fh> };

대부분 $ /를로 설정할 필요가 없습니다 undef.


답변

에서 perlfaq5 : 어떻게 한 번에 모든 전체 파일을 읽을 수 있습니까? :


File :: Slurp 모듈을 사용하여 한 단계로 수행 할 수 있습니다.

use File::Slurp;

$all_of_it = read_file($filename); # entire file in scalar
@all_lines = read_file($filename); # 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( INPUT, $var, -s INPUT );

세 번째 인수는 INPUT 파일 핸들에있는 데이터의 바이트 크기를 테스트하고 해당 바이트를 $ var 버퍼로 읽습니다.


답변

간단한 방법은 다음과 같습니다.

while (<FILE>) { $document .= $_ }

또 다른 방법은 입력 레코드 구분 기호 “$ /”를 변경하는 것입니다. 전역 레코드 구분 기호를 변경하지 않도록 베어 블록에서 로컬로 수행 할 수 있습니다.

{
    open(F, "filename");
    local $/ = undef;
    $d = <F>;
}


답변

로 설정 $/하거나 undef(jrockway의 답변 참조) 모든 파일의 행을 연결하십시오.

$content = join('', <$fh>);

이를 지원하는 모든 Perl 버전에서 파일 핸들에 스칼라를 사용하는 것이 좋습니다.