Text seiten- oder zeilenweise ausgeben in PowerShell: more, less, head, tail

    Texte seitenweise ausgeben mit moreGibt man große Textdateien oder lange Ergeb­nisse eines Cmdlets am Bildschirm aus, dann rauscht der Inhalt ungebremst durch das Konso­len­fenster. Damit man den Output seiten­weise ansehen kann, haben sich unter Unix Pager wie more oder less etabliert. Ähnliche, wenn auch weniger mächtige Tools, bietet auch PowerShell.

    Textorientierte Shells laufen unter modernen Betriebssystemen fast immer im Fenster einer grafischen Oberfläche. Daher geht die Ausgabe von Programmen nicht verloren, wenn sie aus dem sichtbaren Bereich verschwunden ist. Vielmehr kann man zu diesen Inhalten hochscrollen, solange die Größe des Fensterpuffers nicht überschritten wurde. Besonders komfortabel ist dieses Vorgehen aber nicht, so dass weiterhin Bedarf für die bewährten Pager besteht.

    Simpler more-Befehl

    Wie der alte Kommandointerpreter verfügt auch PowerShell über einen more-Befehl. Seine Verwendung ist ebenso einfach wie sein Funktionsumfang. Man kann entweder den Inhalt einer Datei bzw. die Ausgabe eines Cmdlets über eine Pipe an more übergeben oder man teilt ihm über den Parameter -Paths mit, welche Files es anzeigen soll:

    more *.xml

    Dieses Beispiel gibt alle XML-Dateien des aktuellen Verzeichnisses seitenweise auf dem Bildschirm aus. Wie man sieht, sind dabei auch Wildcards zulässig. Der Befehl ist äquivalent zu

    Get-Content *.xml | more

    Die Bedienung des Pagers ist weitgehend identisch mit jener in cmd.exe: Die Leertaste blättert eine Seite und die Eingabetaste eine Zeile nach unten. 'Q' beendet das Tool.

    Ein wesentlicher Nachteil von more besteht darin, dass es erst mit der Ausgabe beginnt, sobald die Inhalte komplett angeliefert wurden. Will man etwa durch eine umfangreiche Log-Datei blättern, dann würden bei

    Get-EventLog Security | more

    erst sämtliche Events ausgelesen, bevor man die ersten Einträge zu sehen bekommt.

    Out-Host als performante Alternative

    PowerShell besitzt mit Out-Host einen zweiten Pager, der in dieser Hinsicht schlauer ist und schon vor dem Ende der Eingabe mit der Darstellung der Inhalte beginnt. Damit das Cmdlet die Texte seitenweise ausgibt, muss man den Parameter -Paging hinzufügen:

    Get-Help Add-ADGroupMember -Detailed | Out-Host -Paging

    Um Tipparbeit zu reduzieren, kann man den vordefinierten Alias oh für Out-Host verwenden:

    Get-EventLog Security | oh -Paging

    Out-Host zeigt die verfügbaren Befehle am Ende der Seite an. Das Ende durch 'Q' quittiert es mit einer Exception.

    Die Bedienung und die Funktionen von Out-Host sind identisch mit more, nur mit dem Unterschied, dass das Cmdlet am unteren Bildschirmrand die Tastenbelegungen anzeigt. Etwas irritierend wirkt nur, dass die Eingabe von 'Q' eine nicht abgefangene Exception wirft.

    Kein Zurückblättern, keine Suche

    Im Vergleich zum altehrwürdigen less unter Unix erscheinen beide Pager in PowerShell etwas mager. So erlauben sie nicht das Zurückblättern oder das Suchen in den angezeigten Inhalten. Als Behelfslösung für Letzteres könnte man die Suchfunktion des Konsolen­programms heranziehen, indem man aus dem Kontextmenü der Titelleiste den Befehl Bearbeiten => Suchen ausführt.

    Den Pagern von PowerShell fehlt eine Suchfunktion, zur Not kann man jene des Konsolenfensters verwenden.

    Andernfalls bleibt nur die Möglichkeit, die Inhalte vor der Übergabe an Out-Host oder more mit Select-String zu filtern.

    Get-Content, Select: Varianten von head und tail

    Beim Umgang mit umfangreichen Textdaten besteht nicht nur der Bedarf, Inhalte Seite für Seite auszugeben. Oft möchte man nur eine bestimmte Zahl an Zeilen am Anfang oder am Ende des Outputs sehen.

    Unter Unix haben sich dafür die Dienstprogramme head und tail etabliert. Deren Aufgabe übernimmt in PowerShell Get-Content, dessen Parameter -First und -Last einen nummerischen Wert für die Anzahl der Zeilen erwarten. Folgendes Beispiel verwendet das Alias gc für Get-Content:

    gc GPORep.xml -Last 10

    Der große Nachteil von Get-Content besteht darin, dass es keine Eingaben über die Pipeline akzeptiert. Daher eignet es sich etwa nicht, die letzten 50 Zeilen aus dem EventLog auszugeben. Zum Glück bietet aber Get-Eventlog mit -newest selbst einen entsprechenden Parameter, um diese Aufgabe zu erledigen. Bei anderen Gelegenheiten gibt es solche Ausweichmöglichkeiten meistens jedoch nicht.

    Dann steht als Alternative Select-Object zur Verfügung, das ebenfalls die Parameter -First und -Last unterstützt. Die Schwäche dieses Cmdlets besteht allerdings wie bei more darin, dass es auf die komplette Eingabe über die Pipe warten muss, bis es die gewünschten Zeilen extrahieren kann.

    Keine Kommentare