2016-08-04 4 views
3

파일의 마지막 줄을 읽으려고합니다. 그리고 특정 파일 행을 읽는 데 사용할 수있는 많은 방법이 있습니다.perl에서 파일의 특정 행을 읽거나 쓰는 가장 좋은 방법은 무엇입니까?

첫째 :

@array=<FILE_HANDLE>; 
    $line=(reverse @array)[0]; 

초 : ReadBackwards 패키지는

$bw = File::ReadBackwards->new('log_file') or 
         die "can't read 'log_file' $!" ; 
$log_line = $bw->readline; 

펄에서, 바람직한 방법 인 것을 알고 싶은 변수로 패키지 또는 저장된 전체 파일 내용을 사용할지 여부.

+1

_best_를 어떻게 정의합니까? 가장 빠른, 가장 메모리 효율적인, 다음 사람을 위해 읽기 쉬운? – simbabque

답변

-2

것은 - 전체 파일을 읽는 것에 의존하지 않는 방법입니다. 파일은 처음부터 시작되며, 귀하의 프로세스 이 끝까지 찾아야합니다. 이것은 코드가 수행하는 것 중 가장 비용이 많이 드는 작업이므로 사용자가 취하는 접근 방식에는 거의 차이가 없습니다. 이 비효율적으로 보일 수 있습니다

my $last_line; 
while (my $line = <$filehandle>) { $last_line = $line }; 
print $last_line,"\n"; 

하지만 다른 것들보다 더 이상 일을하지거야 - 전체 파일을 읽기, 마지막 줄하지만, 모든 것을 버리고 :

그래서 아주 간단한 갈 것입니다.

귀하의 질문에 - 귀하가 특정 줄을 따른다면 - 조건이 충족 될 때 시험 $. (현재 줄 번호)이나 정규 표현식을 사용할 수 있으며 루프가 빠져 나갈 수 있습니다. 따라서 전체 파일을 읽지 않아도된다.

예컨대 :

while (my $line = <$filehandle>) { 
    $last_line = $line; 
    last if $. >= 100; #bails out after we hit line 100. 
    last if m/END FILE/; #looks for 'END FILE' on the line, and bails out. 
}; 
print $last_line,"\n"; 
+4

File :: ReadBackwards는 절대적으로 전체 파일을 읽지 않습니다. – ysth

+0

줄 바꿈을 검색하여 끝에있는 블록을 읽을 수 있습니다. 그렇게하면 전체 파일을 읽을 수 없습니다. – rustyx

+1

@rustyx 네 File :: ReadBackwards가 당신을 대신합니다 – ysth

4

당신의 제목은 당신의 몸과는 다른 질문을.

임의의 큰 파일에서 마지막 (또는 마지막에서 n 번째까지) 행을 읽으려면 File :: ReadBackwards를 사용하십시오. 읽거나 파일에 임의의 한 줄을 작성

, 타이 :: 파일 사용이 필요하기 때문에 대용량 파일의 경우

use Tie::File; 
tie my @line, 'Tie::File', 'filename' or die "unable to open filename: $!"; 
print "line 123 is $line[123]."; 
$line[42] = 'abc'; 
print "line 42 is now abc."; 

를,이 파일 :: ReadBackwards보다 훨씬 더 비싼 것입니다 전체 파일을 수정하려는 행 (또는 음수 인덱스를 사용하는 경우 전체 파일을 통해 읽으므로 그렇게 할 경우 File :: ReadBackwards를 사용하여 파일을 수동으로 업데이트하는 것이 더 낫습니다).

+0

비교를 위해 [this] (http://pastebin.com/2Tqv4qym)은 Tie :: File 스 니펫에 대한 효율적인 대안입니다. 그것은 * 먼 * 적은 메모리를 사용하고 * 훨씬 * 빠릅니다. – ikegami

+0

@ikegami : "메모리 부족"에 대한 번호가 있습니까? – ysth

+1

T :: F는 라인 캐시 (무시할 수있는 크기를 가짐)를 무시하고, 만나는 각 라인의 인덱스를 메모리에 유지합니다. 귀하의 예제에서, 그것은 파일의 모든 라인이 될 것입니다. IIRC, 그것은 내가 사용하고있는 기계에서 라인 당 64 바이트와 같은 것이 었습니다.일반적인 Perl 프로그램 파일의 경우, T :: F를 사용하여 파일을 읽는 것은 실제로 전체 파일을 메모리의 하나의 스칼라에 저장하는 것보다 많은 메모리를 사용합니다! – ikegami

관련 문제