Get-ChildItem: Dateien anzeigen in PowerShell


    Tags: ,

    Powershell-LogoZu den am meisten genutzten Befehlen auf einer Kommandozeile zählen solche für das Auflisten von Dateien und deren Eigenschaften. Unter cmd.exe dient dir diesem Zweck, das PowerShell-Gegenstück ist Get-ChildItem. Wie so häufig, ist das PowerShell-Cmdlet mächtiger, aber dafür bei einigen Aufgaben auch etwas komplizierter.

    Im Vergleich zu dir oder ls unter Unix ist Get-ChildItem aufgrund der Namenskonvention in PowerShell für ein so häufig benötigtes Kommando zu lang. Daher existieren drei vordefinierte Aliase, nämlich gci, ls und dir.

    Letzteres sollte wohl den Wechsel von cmd.exe auf PowerShell vereinfachen, das Problem ist nur, dass auch das Alias die Parameter von Get-ChildItem erwartet und mit den Schaltern des dir-Befehls nichts anfangen kann.

    Schalter für versteckte Dateien und Unterverzeichnisse

    In der einfachsten Variante verhält sich das Cmdlet wie der dir-Befehl unter cmd.exe, sprich der Aufruf ohne Parameter listet die Dateien im aktuellen Verzeichnis auf, wenn auch in einer anderen Darstellung und ohne die Fußzeile mit der Zahl der Dateien und deren Gesamtgröße.

    Wie von dir gewohnt, scheinen dabei Dateien mit dem Hidden- oder System-Attribut nicht auf. Wenn man das möchte, ruft man gci mit dem Parameter -force auf. Will man auch Dateien aus Unterverzeichnissen anzeigen, also ein Äquivalent zu dir /s, dann hängt man den Schalter -recurse (Alias "-r") an:

    Get-ChildItem -Recurse -Force

    Im Unterschied zum dir-Befehl von cmd.exe kann man bei der rekursiven Anzeige angeben, wie tief Get-ChildItem in den Verzeichnisbaum hinabgehen soll:

    Get-ChildItem -Recurse -Depth 1

    Dieser Aufruf würde nur den Inhalt des aktuellen Verzeichnisses und jener eine Ebene darunter ausgeben.

    Mehrere Pfade in einem Aufruf

    Ein wesentlicher Unterschied zu dir besteht darin, dass Get-ChildItem nicht nur die Dateien unterhalb eines Verzeichnisses anzeigen kann, sondern den Inhalt mehrerer Teilbäume auflistet, wenn man ihm die Pfade durch Komma getrennt übergibt:

    gci .\Documents, .\Downloads, .\Pictures

    Die eigentliche Stärke von PowerShell und damit auch von gci zeigt sich, wenn man das Ergebnis nach verschiedenen Kriterien filtern oder weiterverarbeiten möchte.

    Einfache Fälle wären zum Beispiel, dass man nur die Dateinamen anzeigen oder die Zahl der ermittelten Dateien sehen möchte. Ersteres lässt sich durch das Anhängen des Parameters -name bewerkstelligen.

    Welche Eigenschaften eines FileInfo-Objekts dafür in Frage kommen, kann man herausfinden, indem man die Ausgabe von Get-ChildItem an Get-Member weiterleitet:

    Get-ChildItem |  Get-Member -MemberType CodeProperty, Property

    Eigenschaften eines FileIfo-Objekts mit Get-Member anzeigen

    Dateien in Verzeichnissen zählen

    Das Zählen der Dateien ist ebenfalls recht simpel, weil Get-ChildItem ein Array (Collection) von FileInfo-Objekten zurückgibt. Daher muss man nur über die count-Eigenschaft abfragen, wie viele Mitglieder die Collection hat:

    (gci .\Documents, .\Downloads, .\Pictures -filter *.zip).count

    Dieser Aufruf ermittelt die Anzahl der ZIP-Archive unterhalb der drei angegebenen Verzeichnisse.

    Alternativ kann man dafür eine Pipeline mit Measure-Object verwenden:

    Get-childItem .\Downloads\*.zip | Measure-Object -sum Length |
    select @{n="Dateien insgesamt";e={$_.count}}
    , @{n="MBytes";e={$_.sum / 1MB}}

    Nach Attributen filtern

    Eine häufige Anwendung von dir besteht darin, nur Dateien anzuzeigen, die ein bestimmtes Attribut gesetzt haben, also zum Beispiel dir /ad, um nur Verzeichnisse zu erfassen. PowerShell bietet hierfür mit Directory (Alias "dir") einen eigenen Schalter:

    Get-ChildItem -Directory

    Weitere Schalter, um nach Attributen zu filtern, gibt es für schreibgeschützt (ReadOnly), versteckt (Hidden) und System:

    gci -Hidden -ReadOnly

    Um alle Dateien mit Archivattribut anzuzeigen, könnte man so vorgehen:

    gci -force | where {$_.mode -match "a"}

    oder

    gci -force | where {$_.attributes -match "Archive"}

    Bei mode und attributes handelt es sich um zwei von vielen Eigenschaften eines FileInfo-Objekts, auf die man für verschiedene Zwecke zurückgreifen kann. So lassen sich etwa mittels length alle Dateien anzeigen, die eine bestimmte Größe überschreiten (in diesem Fall 250000 Bytes):

    gci .\Pictures -recurse -filter *.png | where {$_.length -gt 250000}

    Um alle Attribute der Dateien im aktuellen Verzeichnis auszugeben, kann man Get.ChildItem so aufrufen:

    Get-childItem | select FullName, Attributes

    Attribute von Dateien mit Hilfe von Select-Object anzeigen

    Dateiliste sortieren

    Die Eigenschaften von Dateien kann man auch heranziehen, um sie darüber zu sortieren, etwa nach der Erweiterung:

    gci .\documents -force | sort -property extension

    Individuelles Anpassen der Ausgabe

    Durch den gezielten Zugriff auf die Eigenschaften von FileInfo-Objekten kann man auch die Ausgabe von gci nach Gutdünken verändern:

    gci .\documents -force | where {$_.mode -notmatch "r"} |
    select name, length

    In diesem Beispiel würden alle nicht schreibgeschützten Dateien unterhalb von Documents erfasst, die Ausgabe reduziert sich dabei auf den Namen und die Größe der Datei.

    Als weitere Eigenschaften, die man auf diese Weise gezielt extrahieren kann, existieren zum Beispiel der volle Dateiname inklusive Pfad (FullName), der Dateiname ohne Extension (BaseName) oder nur der Pfad (Directory).

    Täglich Know-how für IT-Pros mit unserem Newsletter

    Wir ver­wenden Ihre Mail-Adresse nur für den Ver­sand der News­letter.
    Es erfolgt keine per­sonen­be­zogene Auswertung.

    Bild von Wolfgang Sommergut
    Wolfgang Sommergut hat lang­jährige Erfahrung als Fach­autor, Berater und Kon­ferenz­sprecher zu ver­schie­denen Themen der IT. Da­ne­ben war er als System­ad­mi­ni­stra­tor und Con­sultant tätig.
    // Kontakt: E-Mail, XING, LinkedIn //

    Verwandte Beiträge

    Weitere Links

    1 Kommentar

    Verständliche Erklärung, danke :)