2013-02-17 26 views
15

Một chương trình đơn giản với while(<>) xử lý các tệp được đặt làm đối số (./program 1.file 2.file 3.file) và đầu vào chuẩn của hệ thống Unix.Perl - trong khi (<>) xử lý tệp

Tôi nghĩ rằng nó kết hợp chúng lại với nhau trong một tệp và công việc theo từng dòng. Vấn đề là, làm cách nào để biết rằng tôi đang làm việc với tệp đầu tiên? Và sau đó với cái thứ hai.

Ví dụ đơn giản, tôi muốn in nội dung của tệp trong một dòng.

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

trông khá giống với các SO chủ đề sau: http: //stackoverflow.com/questions/13584944/which-file-is-perl-diamond-operator-currently-reading-from – varnie

Trả lời

18

hành Viên kim cương không nối các tập tin, nó chỉ mở ra và đọc chúng liên tiếp. Làm thế nào bạn kiểm soát điều này phụ thuộc vào cách bạn cần nó kiểm soát. Một cách đơn giản để kiểm tra khi chúng ta đã đọc những dòng cuối cùng của một file là sử dụng eof:

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

Bạn cũng có thể xem xét một bộ đếm để theo dõi các tập tin đó để bạn chế biến

$counter++ if eof; 

Lưu ý rằng số này sẽ tăng thêm một ở số dòng cuối cùng của tệp, do đó, không sử dụng nó sớm.

Nếu bạn muốn theo dõi các dòng số $. trong xử lý tập tin hiện tại, bạn có thể close file argv xử lý để thiết lập lại bộ đếm này:

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

Cảm ơn bạn, câu trả lời của bạn đã giúp rất nhiều! –

+0

@MantasMarcinkus Bạn được chào đón. – TLP

+0

Xem 'perldoc -f eof' để biết thêm thông tin về việc phát hiện ranh giới giữa các tập tin được đọc bởi toán tử' <> '. – chepner

10

<> là trường hợp đặc biệt của toán tử readline. Nó thường mất một filehandle: <$fh>.

Nếu tập tin tay trái bị bỏ đi, thì sử dụng tập tin ma thuật ARGV.

Nếu không có đối số dòng lệnh nào được cung cấp, thì ARGVSTDIN. Nếu các đối số dòng lệnh được đưa ra, sau đó, ARGV sẽ là open được chỉnh sửa thành từng đối số. Điều này tương tự như

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

Biến số $ARGV là có thật và giữ tên tệp của tệp hiện đang mở.

Xin lưu ý rằng dạng hai arg là open (có thể được sử dụng ở đây phía sau hậu trường), là khá không an toàn. Tên tập tin rm -rf * | có thể không làm những gì bạn muốn.

1

Tên của tệp hiện tại cho <> được chứa trong đặc biệt $ARGVvariable.

Bạn có thể kết hợp chéo danh sách tệp của mình từ mảng tham số @ARGV với tên tệp hiện tại để lấy vị trí của tệp trong danh sách. Giả sử các thông số duy nhất mà bạn mong đợi được tên tập tin, bạn chỉ có thể làm:

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

while (<>) { 
    my $file_number = $filename_positions{$ARGV}; 
    #... if ($file_number == 0) { #first file  
} 
Các vấn đề liên quan