Wie kann ich in Perl aus mehreren Dateihandles in einer Schleife lesen?

7

Ich habe mich gefragt, wie ich das in Perl umsetzen könnte:

%Vor%

Ich bin mir nicht sicher, wie man in zwei Zeilen in einer while -Schleife eine Zeile nach der anderen lesen kann.

    
Ryan 12.07.2012, 15:47
quelle

3 Antworten

11

Scheint so, als hättest du deine Antwort fast selbst geschrieben. Suchen Sie einfach nach eof für beide Datei-Handles, so:

%Vor%

Mehr lesen:

TLP 12.07.2012 15:57
quelle
10

Hinweis: Ich habe meine Antwort als Antwort auf die Kommentare von @zostay und @ jm666 erweitert.

Der erste Schritt zu einer effizienten, klaren und prägnanten Antwort auf diese Frage beginnt mit der Idee, dass Variablen gehen in einem Aggregat . Also, das Array @fh wird die Dateihandles enthalten, von denen wir gleichzeitig lesen.

Dann können wir eine Zeile aus jedem Dateihandle lesen und sie in einem Array unter Verwendung der <> speichern Operator in Verbindung mit Karte . map verwendet eine Transformationsregel und eine Liste und gibt eine andere Liste zurück. Daher:

%Vor%

nimmt die Dateihandles in @fh und liest jeweils eine einzelne Zeile aus (Anmerkung Skalar ) und legt diese Zeilen in @lines . Dies ist eine one-to-one Transformation von @fh .

Wie die Dokumentation für <> angibt, gibt <> einen nicht definierten Wert zurück, wenn das Dateiende erreicht ist oder ein Fehler aufgetreten ist.

Nun können Sie überprüfen, ob wir erfolgreich aus allen Dateien lesen können, indem Sie überprüfen, ob die Anzahl definierte Zeilen enthält ist die gleiche wie die Anzahl der Dateihandles. grep wählt Elemente einer Liste aus, die ein bestimmtes Kriterium erfüllen. Daher

%Vor%

würde prüfen, ob die Anzahl der Dateihandles in @fh mit der Anzahl der definierten Elemente in @lines übereinstimmt. Allerdings kann das @fh , das auf beiden Seiten dieses Vergleichs erscheint, in der Tat verwirrend sein, so dass eine alternative Methode zur Überprüfung der dort sind keine undefinierten Elemente in @lines ist:

%Vor%

Wenn Sie diese Bedingung in eine Schleife während einfügen möchten, müssen Sie Folgendes schreiben:

%Vor%

Wenn Sie jedoch mit bis fortfahren, können Sie einfach Folgendes schreiben:

%Vor%

Dies bedeutet ", bis mindestens eine der Leselinien einen nicht definierten Wert zurückgibt, führen Sie den Körper der Schleife " aus.

Beachten Sie, dass Perls eof anders ist als Cs eof . Die Dokumentation für Perls eof stellt Folgendes fest:

  

Praktischer Hinweis: Sie müssen fast nie eof in Perl verwenden, weil die Eingabeoperatoren normalerweise undef zurückgeben, wenn sie keine Daten mehr haben oder einen Fehler entdecken.

Wenn Sie eof jedes Mal durch die Schleife überprüfen, verdoppeln Sie Ihr Datei-IO, weil " diese Funktion tatsächlich ein Zeichen liest und dann ungetc s it ."

Ich gebe fast immer ein eigenständiges lauffähiges Beispiel mit meinem Code. Im Folgenden wollte ich nicht auf bestimmte Dateien auf Ihrem System zurückgreifen, daher verwende ich die immer verfügbaren DATA und STDIN Punkte. Im Gegensatz zur Verwendung der Funktion eof müssen Sie sich bei der Verwendung dieser Methode keine Gedanken darüber machen, wo Sie gerade lesen: Sie müssen nur wissen, ob eine Readline in einer der Dateien einen nicht definierten Wert zurückgegeben hat. Es kann auch mit einer beliebigen Anzahl von Dateihandles verwendet werden. Außerdem haben Sie die Dateihandles wirklich nicht in ein Array eingefügt, aber wie gesagt, verwandte Variablen gehören zu einem Aggregat, wenn Sie also Dinge wie

eingeben %Vor%

beachte, dass du ein Array benutzt haben solltest, um die Dateihandles zu speichern .

%Vor%

Dieses Beispielskript hört auf, nach Ihrer Eingabe in STDIN zu fragen, wenn die Zeilen in DATA erschöpft sind. Wenn Sie im Skript keine abschließenden Leerzeilen haben, müssen Sie vor dem Skriptende drei vier Zeilen eingeben.

Wenn Sie jetzt wissen möchten, welche Dateihandles das Ende erreicht haben, würden Sie zu etwas wie:

wechseln %Vor%

Wichtig

Die obigen Schleifen sind so konzipiert, dass sie aufhören, wenn eine der Dateien erschöpft ist. Auf der anderen Seite möchten Sie möglicherweise, dass die Loops ausgeführt werden, bis alle Dateien erschöpft sind. In diesem Fall würden Sie verwenden:

%Vor%     
Sinan Ünür 12.07.2012 16:06
quelle
2

Eine andere einfache Lösung ohne explizite eof() Prüfung würde folgendermaßen aussehen:

%Vor%

Dies nutzt die Tatsache, dass <> undef if & amp; nur wenn Sie am Ende der Datei sind.

    
Ken Williams 16.07.2012 14:15
quelle

Tags und Links