Dateien mit regulären Ausdrücken suchen
Unter Windows durchsucht man die lokale Festplatte meist nur mit Hilfe des “Suchen”-Dialogs aus dem Startmenü. Diese Methode erweist sich jedoch als unzureichend, wenn etwas komplexere Abfragen durchgeführt werden sollen. Spätestens, wenn der Dateiname oder der Pfad mit einem regulären Ausdruck verglichen werden soll, ist schluss. Aber wer braucht schon einen “Suchen”-Dialog, wenn Microsoft mit der Powershell völlig neue Möglichkeiten geschaffen hat?
Woher, wohin
Die Powershell gehört seit Windows 7 zum Lieferumfang von Windows. Zu finden ist sie - nach der Installation - im Ordner “Zubehör” oder einfach über die Startmenüsuche (Stichwort: Powershell).
Dateiliste
Um in Powershell die Dateiliste des aktuellen Ordners zu erhalten genügt es, das CmdLet Get-ChildItem
aufzurufen. Wer es gerne kürzer haben möchte, kann die Aliase dir
oder ls
verwenden.
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 08.08.2012 14:51 .eclipse
d---- 30.08.2012 08:34 Desktop
d---- 29.08.2012 17:12 Eigene Dateien
d-r-- 29.09.2011 10:46 Favorites
d---- 25.05.2010 10:32 Lokale Einstellungen
d-r-- 27.08.2012 15:23 My Documents
d-r-- 16.03.2010 07:59 Start Menu
d---s 04.08.2010 11:34 UserData
----- 22.09.2010 10:24 1582 _viminfo
Natürlich möchte man auch manchmal versteckte Dateien sehen. Get-ChildItem -force
erledigt das.
Weniger ist mehr
Fein, und wo sind jetzt die tollen Filtermöglichkeiten?
Das ist eine berechtigte Frage. Da die Powershell ihre Informationen in Form von Objekten verwaltet, gibt es viel mehr Informationen zu einem Verzeichniseintrag als man mit bloßem Auge sieht. Die Zeile Get-ChildItem|Select-Object -First 1|Get-Member *
gibt eine Übersicht der Eigenschaften und Methoden eines Verzeichniseintrags zurück1:
Name MemberType
---- ----------
Mode CodeProperty
Create Method
CreateObjRef Method
CreateSubdirectory Method
Delete Method
Equals Method
GetAccessControl Method
GetDirectories Method
GetFiles Method
GetFileSystemInfos Method
GetHashCode Method
GetLifetimeService Method
GetObjectData Method
GetType Method
InitializeLifetimeService Method
MoveTo Method
Refresh Method
SetAccessControl Method
ToString Method
PSChildName NoteProperty
PSDrive NoteProperty
PSIsContainer NoteProperty
PSParentPath NoteProperty
PSPath NoteProperty
PSProvider NoteProperty
Attributes Property
CreationTime Property
CreationTimeUtc Property
Exists Property
Extension Property
FullName Property
LastAccessTime Property
LastAccessTimeUtc Property
LastWriteTime Property
LastWriteTimeUtc Property
Name Property
Parent Property
Root Property
BaseName ScriptProperty
Gerade die Einträge, welche den “MemberType” “Property” besitzten sind für uns interessant:
Eigenschaft | Beschreibung |
---|---|
Attributes | Attribute der Datei oder des Verzeichnisses. |
CreationTime | Erstellungszeitpunkt der Datei oder des Verzeichnisses. |
CreationTimeUtc | Enthält den Wert von CreationTime in UTC/GMT. |
Exists | Gibt an ob die Datei existiert. Sollte bei allen Dateien die über Get-ChildItem gefunden werden “true” sein. |
Extension | Gibt die Dateierweiterung der Datei oder des Verzeichnisses an. Dies ist normalerweise der Text nach dem letzten “.”. |
FullName | Gibt den vollständigen Namen der Datei oder des Verzeichnisses (inkl. des Pfades) an. |
LastAccessTime | Zeitpunkt des letzten Zugriffs auf die Datei oder das Verzeichnis. |
LastAccessTimeUtc | Enthält den Wert von LastAccessTime in UTC/GMT. |
LastWriteTime | Zeitpunkt des letzten Schreibzugriffs auf die Datei oder das Verzeichnis. |
LastWriteTimeUtc | Enthält den Wert von LastWriteTime in UTC/GMT. |
Name | Enthält den Dateinamen bzw. Verzeichnisnamen ohne Pfad. |
Parent | Enthält ein Objekt, welches das übergeordnete Verzeichnis repräsentiert. |
Root | Enthält ein Objket, welches das Laufwerk repräsentiert, in welchem die Datei abgelegt wurde. |
Natürlich kann Get-ChildItem
auch verwendet werden um andere Powershell-Namespaces zu durchlaufen (z. B. kann man darüber auch in der Registry suchen). Aber das ist eine andere Geschichte.
…und wie filtert man jetzt nach dem ganzen Zeug?
Hierfür gibt es das Where
CmdLet, welches sich auch durch ein Fragezeichen abkürzen lässt. Diesem CmdLet übergibt man ein Stück Powershell-Script, mit welchem man dann die Dateien filtern kann. Zum Beispiel zeigt Get-ChildItem|Where {$_.Name -match "^b.*"}
alle Dateien an, deren Name mit einem “b” beginnt2. Innerhalb des Code-Blocks, welcher von Match verwendet wird, dient die Variable $_
dazu, das aktuell geprüfte Element zu bestimmen. Der Block muss dann entweder “true” (1) oder “false” (0) zurückliefern, je nach dem, ob man die Datei im Ergebnis haben will, oder nicht. Der langweiligste Code-Block wäre damit Get-ChildItem|Where {1}
. Er würde alle Dateien selektieren.
Sieht man sich die Hilfe zu den Vergleichsoperatoren3 an, erhält man gute Hinweise, welche Vergleichsoperatoren in Powershell noch möglich sind:
Operator | Beschreibung |
---|---|
-eq | Prüft auf Gleichheit. |
-ne | Prüft auf Ungleichheit (Gegenteil von -eq ). |
-gt | Größer als. |
-ge | Größer oder gleich. |
-lt | Kleiner als. |
-le | Kleiner oder gleich. |
-like | Übereinstimmungsprüfung welche das Wildcard (*) unterstützt. Ähnelt den Filtern in normalen DOS-Befehlen wie dir . |
-notlike | Gegenteil von -like . Trifft immer dann zu, wenn keine Übereinstimmung gefunden wird. |
-match | Übereinstimmungsprüfung mit einem regulären Ausdruck (Groß-/Kleinschreibung wird ignoriert). |
-cmatch | Übereinstimmungsprüfung mit einem regulären Ausdruck (Groß-/Kleinschreibung wird beachtet). |
-notmatch | Gegenteil von -match . Trifft immer dann zu, wenn keine Übereinstimmung gefunden wird. |
-contains | Prüft ob eine Liste den angegebene String enthält. |
-notcontains | Gegenteil von -contains . Trifft immer dann zu, wenn das Element nicht in der Liste gefunden wird. |
Wie man sieht, bietet der Where
-Filter eine Menge an Möglichkeiten.
Tiefer und tiefer
Manchmal möchte man nicht nur in der aktuellen Ebene des Verzeichnisbaums, sondern auch in Unterordnern suchen. Dies erlaubt der Paramter -Recurse
. Get-ChildItem C: -Recurse
liefert also alle Dateien auf dem Laufwerk C:
.
Beispiele
Hier noch einige Beispiele, wie man diese mächtige Suchfunktion effektiv nutzen kann:
Beispiel 1
Get-ChildItem|Where {$_.Name -match "^b.*"}
Das hatten wir oben schon. Es zeigt alle Dateien an, welche mit einem “b” beginnen. Hierbei wird nicht zwischen Groß- und Kleinschreibung unterschieden.
Beispiel 2
Get-ChildItem -Force|Where {$_.Attributes -contains "Hidden"}
Zeigt alle versteckten Dateien an.
Beispiel 3
Get-ChildItem -Force|Where {$_.Length -gt 1000}
Sucht alle Dateien, deren Größe 1000 Byte übersteigt.
Beispiel 4
Get-ChildItem C: -Recurse|Where {(New-Timespan $_.CreationTime $(Get-Date)).TotalDays -lt 10}|Select-Object FullName,CreationTime
Gibt den Pfad aller Dateien aus, die in den letzten 10 Tagen erstellt wurden. Hierbei wird das CmdLet New-Timespan
verwendet, welches aus zwei Zeitangaben einen Zeitraum bildet.
Beispiel 5
Get-ChildItem|Where {$_.Attributes -contains "Directory"}|ForEach-Object {$_|Add-Member -name Length -membertype NoteProperty -value $($_|Get-ChildItem -Recurse |Measure-Object -Property length -sum).Sum -passthru}
Ermittelt die Größe der einzelnen Unterordner des aktuellen Ordners. Normalerweise wird die Eigenschaft “Length” für Ordner nicht befüllt. Über ein ForEach-Konstrukt wird aber für jedes Directory (Attributfilter) die Length-Eigenschaft mit der Summe der Größen der Kinder belegt. Dies geschieht über das CmdLet Add-Member
, welches eine neue Eigenschaft zu einem Powershell-Objekt hinzufügt.
Beispiel 6
Get-ChildItem -Recurse -Force|Sort-Object -Property Length -Descending|Select -First 20|Select FullName, Length|Out-GridView
Zeigt eine grafische Liste der zwanzig größten Dateien in allen Unterordnern des aktuellen Ordners an.
Beispiel 7
Get-ChildItem|Where {! $_.PSIsContainer}|ForEach-Object {$_|Add-Member -name Key -membertype NoteProperty -value $(Get-Random) -passthru}|Sort-Object -Property Key|Select-Object FullName
Gibt die Namen (inkl. Pfad) der Dateien im aktuellen Verzeichnis (PSIsContainer
sorgt dafür, dass Unterordner übersprungen werden) in zufälliger Reihenfolge aus. Hierfür wird jeder Datei ein zufälliger Schlüssel “Key” hinzugefügt und anschließend nach diesem sortiert. Kann verwendet werden, um zufällige Playlists ohne doppelte Einträge zu erzeugen.