2013-02-17 2 views
15

간단한 프로그램 while(<>)은 인수 (./program 1.file 2.file 3.file)와 Unix 시스템의 표준 입력으로 주어진 파일을 처리합니다.Perl - while (<>) 파일 처리

나는이 파일들을 하나의 파일로 연결하고 작업을 줄 단위로 생각한다. 문제는 첫 번째 파일로 작업하고 있음을 어떻게 알 수 있습니까? 그리고 두 번째로.

간단한 예를 들어 파일의 내용을 한 줄에 인쇄하고 싶습니다.

while(<>){ 
    print "\n" if (it's the second file already); 
    print $_; 
} 
+2

: 현재 파일 핸들에 행 번호 $.를 추적하려면

,이 카운터를 재설정 할 ARGV 파일 핸들을 close 수 있습니다 : //stackoverflow.com/questions/13584944/which-file-is-perl-diamond-operator-currently-reading-from – varnie

답변

18

다이아몬드 운영자가 파일을 연결하지 않고, 그냥 열리고 연속을 읽습니다. 어떻게 통제 할 것인가는 통제가 필요한 방식에 달려 있습니다. 우리가 파일의 마지막 라인을 읽을 때 확인하는 간단한 방법은 eof가 사용하는 것입니다 : 당신이 처리하는 순서로 파일을 추적하기 위해

while (<>) { 
    chomp;    # remove newline 
    print;    # print the line 
    print "\n" if eof; # at end of file, print a newline 
} 

또한 카운터를 고려할 수

$counter++ if eof; 

이 수는 파일의 마지막 줄인에서 1 씩 증가하므로 조기에 사용하지 마십시오. HTTP : 거의 유사한 다음 SO 주제에 보이는

while (<>) { 
    print "line $. : ", $_; 
    close ARGV if eof; 
} 
+0

감사합니다. 답변이 도움이되었습니다. –

+0

@MantasMarcinkus 여러분을 환영합니다. – TLP

+0

'<> '연산자로 읽은 파일들 사이의 경계를 탐지하는 것에 대한 더 자세한 정보는'perldoc -f eof'를보십시오. – chepner

10

<>은 readline 연산자의 특별한 경우입니다. 대개 파일 핸들이 필요합니다 : <$fh>.

파일 핸들을 빠뜨리면 마법 파일 ARGV이 사용됩니다.

명령 줄 인수가 제공되지 않으면 ARGVSTDIN입니다. 커맨드 라인 인수가 주어지면 ARGV은 차례대로 각각 open이됩니다. 이는 $ARGV 변수가 진짜

# Pseudocode 
while ($ARGV = shift @ARGV) { 
    open ARGV, $ARGV or do{ 
    warn "Can't open $ARGV: $!"; 
    next; 
    }; 
    while (<ARGV>) { 
    ...; # your code 
    } 
} 

유사하며, 현재 열려있는 파일의 파일 이름을 보유하고 있습니다.

open의 두 인수 형식 (아마도 여기에서 사용되는 것 같습니다)은 매우 안전하지 않습니다. 파일 이름 rm -rf * |은 원하는 것을 수행하지 않을 수 있습니다.

1

<>의 현재 파일 이름은 $ARGVvariable에 포함되어 있습니다.

@ARGV 매개 변수 배열의 파일 목록을 현재 파일 이름과 교차 일치시켜 목록에서 파일의 위치를 ​​가져올 수 있습니다. 당신이 기대하는 유일한 매개 변수 파일 이름이되어 가정 할 때, 당신은 간단하게 수행 할 수 있습니다

my %filename_positions = map { ($ARGV[$_] => $_) } 0..$#ARGV; 

while (<>) { 
    my $file_number = $filename_positions{$ARGV}; 
    #... if ($file_number == 0) { #first file  
}