Ich versuche einen prägnanten Shell-One-Liner zu finden, der mir alles geben wird Zeilen in einer Datei bis zu ein Muster.
Der Anwendungsfall besteht darin, alle Zeilen in einer Protokolldatei auszugeben, bis ich einige finde Markierung, die anzeigt, dass der Server neu gestartet wurde.
Hier ist eine dumme Shell-only-Methode:
%Vor%Ein etwas zuverlässigerer Perl-Weg, der die Datei auf stdin nimmt:
%Vor%Und natürlich könnten Sie das effizienter tun, wenn Sie die Datei öffnen, suche bis zum Ende und suche zurück, bis du eine passende Zeile gefunden hast.
Es ist einfach, alles ab dem ersten Vorkommen zu drucken, z. B .:
%Vor%Aber ich habe mir keine Möglichkeit ausgedacht, um alles ab dem letzten zu drucken Vorkommen.
Hier ist eine sed-only-Lösung. So drucken Sie jede Zeile in $file
beginnend mit die letzte Zeile, die mit $pattern
übereinstimmt:
Beachten Sie, dass dies wie Ihre Beispiele nur dann funktioniert, wenn die Datei das Muster enthält. Andernfalls wird die gesamte Datei ausgegeben.
Hier ist eine Zusammenfassung dessen, was es macht, mit sed-Befehlen in Klammern:
Beachten Sie auch, dass es bei sehr großen Dateien wahrscheinlich langsam wird, da jede Single-Pass-Lösung eine Reihe von Zeilen im Speicher behalten muss.
Ich schlage eine Vereinfachung Ihres Shell-Skripts vor:
%Vor%Es ist wesentlich prägnanter, weil es:
+
des Tails, um von der gegebenen Zeile bis zum Ende zu drucken, anstatt die Entfernung von dort bis zum Ende zu berechnen. Und es behebt einen Fehler, indem er $ file zitiert (so wird es bei Dateien funktionieren, deren Namen Leerzeichen enthalten).
Der Titel und die Beschreibung dieser Fragen stimmen nicht überein.
Für den Titel der Frage +1 für die Antwort von @David W. Auch:
%Vor%Für die Frage im Körper haben Sie bereits einige Lösungen.
Beachten Sie, dass tac
wahrscheinlich spezifisch für Linux ist. Es scheint nicht in BSD oder OSX zu existieren. Wenn Sie eine Lösung mit mehreren Plattformen möchten, verlassen Sie sich nicht auf tac.
Natürlich erfordert jede Lösung, dass Ihre Daten entweder im Speicher gespoolt oder einmal zur Analyse und ein zweites Mal zur Verarbeitung gesendet werden. Zum Beispiel:
%Vor% Beachten Sie, dass meine Verwendung von tail
für FreeBSD ist. Wenn Sie Linux verwenden, benötigen Sie wahrscheinlich tail -n $n $tmpfile
.
Rob Davis hat mir gezeigt, was Sie gesagt wollten, was Sie wirklich wollten:
Du hast gesagt:
Ich versuche einen prägnanten Shell-One-Liner zu finden, der mir alle Zeilen in einer Datei bis ein Muster geben wird.
Aber dann, am Ende deines Beitrags, hast du gesagt:
Aber ich habe keine Möglichkeit gefunden, alles ab zu drucken.
Ich habe Ihnen bereits die Antwort auf Ihre erste Frage gegeben. Hier ist eine einzeilige Antwort für Ihre zweite Frage: Drucken von einem regulären Ausdruck bis zum Ende der Datei:
%Vor%Ein ähnlicher Perl-One-Liner:
%Vor%