Rekursive Dateisuche mit PowerShell

238

Ich suche in allen Ordnern nach einer Datei.

Copyforbuild.bat ist an vielen Stellen verfügbar, und ich möchte rekursiv suchen.

$File = "V:\Myfolder\**\*.CopyForbuild.bat"

Wie kann ich das in PowerShell machen?

Samselvaprabu
quelle

Antworten:

393

Verwenden Sie das Cmdlet Get-ChildItem mit dem -RecurseSchalter:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force
Shay Levy
quelle
1
Es scheint ein Problem zu geben, dass die gesamte Suche abgebrochen wird, wenn es in ein Verzeichnis läuft, auf das Sie keine Zugriffsberechtigung haben, da der Prozess beendet wird. Gibt es einen Weg, das zu umgehen?
deed02392
6
Versuchen Sie, den Parameter ErrorAction auf Continue oder SilentlyContinue zu setzen (falls sein Wert nicht wie angegeben ist).
Shay Levy
22
Ein kürzerer Weg, genau das Gleiche zu tun: cd V:\MyFoldergefolgt vonls -r -inc CopyForBuild.bat
Orion Edwards
8
Also, was die Kommentatoren oben bedeuten, ist ...ls -r -ea silentlycontinue -fo -inc "filename.txt" | % { $_.fullname }
Andrew
Ich habe diese Antwort angepasst, um eine Teilzeichenfolge zu erstellen, indem ich das astrische Symbol ( *) am Ende des Dateinamens hinzufügte . ****** LINE1: $File = "Microsoft.OData.Core.NetFX35.V7*"LINE2: $Folder = "C:\Program Files"LINE3:Get-ChildItem -Path $Folder -Filter $File -Recurse -ErrorAction SilentlyContinue -Force
SherlockSpreadsheets
37

Ich verwende dies, um Dateien zu finden und PowerShell den gesamten Pfad der Ergebnisse anzeigen zu lassen:

dir -Path C:\FolderName -Filter FileName.fileExtension -Recurse | %{$_.FullName}

Sie können den Platzhalter immer *im FolderNameund / oder verwenden FileName.fileExtension. Beispielsweise:

dir -Path C:\Folder* -Filter File*.file* -Recurse | %{$_.FullName}

Im obigen Beispiel wird jeder Ordner im C:\Laufwerk durchsucht, der mit dem Wort beginnt Folder. Wenn Sie also einen Ordner mit dem Namen haben FolderFoound FolderBarPowerShell die Ergebnisse dieser beiden Ordner anzeigt.

Gleiches gilt für den Dateinamen und die Dateierweiterung. Wenn Sie nach einer Datei mit einer bestimmten Erweiterung suchen möchten, aber den Namen der Datei nicht kennen, können Sie Folgendes verwenden:

dir -Path C:\FolderName -Filter *.fileExtension -Recurse | %{$_.FullName}

Oder umgekehrt:

dir -Path C:\FolderName -Filter FileName.* -Recurse | %{$_.FullName}
BinaryJoe01
quelle
4
Ich finde diese Antwort äußerst nützlich, da sie einen bestimmten Anwendungsfall anspricht - tatsächlich die Datei verwenden möchte, nach der Sie suchen. Die | Um Ihnen den vollständigen Namen der Datei zu geben, fehlt in den anderen Antworten etwas.
Newteq Developer
1
Ich muss hier @ Sanity1123 zustimmen. Wenn Sie die Datei tatsächlich verwenden möchten, benötigen Sie den vollständigen Pfad zur Datei. IMHO sollte dies die akzeptierte Antwort sein.
Uceumern
31

C:\UsersVerwenden Sie beim Durchsuchen von Ordnern, bei denen aufgrund der Sicherheit möglicherweise ein Fehler auftritt (z. B. ), den folgenden Befehl:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force
Mötz
quelle
12
Get-ChildItem V:\MyFolder -name -recurse *.CopyForbuild.bat

Wird auch funktionieren

user3303020
quelle
Wenn Sie Ergebnisse in eine Datei ausgeben möchten, können Sie am Ende des Befehls `> path_to_filename.txt` hinzufügen.
Gwen Au
7

Hier ist die Methode, die ich mir nach dem Kämpfen endlich ausgedacht habe:

Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*

Verwenden Sie Folgendes, um die Ausgabe sauberer zu machen (nur Pfad):

(Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*).fullname

Verwenden Sie Folgendes, um nur das erste Ergebnis zu erhalten:

(Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*).fullname | Select -First 1

Nun zu den wichtigen Dingen:

So suchen Sie nur für Dateien / Verzeichnisse Sie nicht verwenden , -Fileoder -Directory(siehe unten , warum). Verwenden Sie dies stattdessen für Dateien:

Get-ChildItem -Recurse -Path ./path*/ -Include name* | where {$_.PSIsContainer -eq $false}

und entfernen Sie die -eq $falsefor-Verzeichnisse. Hinterlassen Sie keine nachgestellten Platzhalter wie bin/*.

Warum nicht die eingebauten Schalter verwenden? Sie sind schrecklich und entfernen Merkmale zufällig. Um beispielsweise -Includeeine Datei verwenden zu können, müssen Sie den Pfad mit einem Platzhalter beenden. Dies deaktiviert jedoch den -RecurseSchalter, ohne Ihnen Folgendes zu sagen:

Get-ChildItem -File -Recurse -Path ./bin/* -Include *.lib

Sie würden denken, das würde Ihnen alle *.libs in allen Unterverzeichnissen geben, aber es wird nur die oberste Ebene von suchen bin.

Um nach Verzeichnissen zu suchen, können Sie verwenden -Directory, aber dann müssen Sie den nachfolgenden Platzhalter entfernen. Aus irgendeinem Grund wird dies nicht deaktiviert -Recurse. Aus diesen Gründen empfehle ich, die eingebauten Flags nicht zu verwenden.

Sie können diesen Befehl erheblich verkürzen:

Get-ChildItem -Recurse -Path ./path*/ -Include name* | where {$_.PSIsContainer -eq $false}

wird

gci './path*/' -s -Include 'name*' | where {$_.PSIsContainer -eq $false}
  • Get-ChildItem ist aliasiert auf gci
  • -Path ist standardmäßig Position 0, sodass Sie nur den ersten Argumentpfad erstellen können
  • -Recurse ist aliasiert auf -s
  • -Include hat keine Abkürzung
  • Verwenden Sie einfache Anführungszeichen für Leerzeichen in Namen / Pfaden, damit Sie den gesamten Befehl mit doppelten Anführungszeichen umgeben und in der Eingabeaufforderung verwenden können. Wenn Sie es umgekehrt machen (mit einfachen Anführungszeichen umgeben), entstehen Fehler
hLk
quelle
6

Versuche dies:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse | Where-Object { $_.Attributes -ne "Directory"}
Siebenfach
quelle
2
Sie können auch verwenden | Where-Object { !$_PSIsContainer }, um Ordner auszuschließen
Gargravarr
5

Filtern mit Platzhaltern:

Get-ChildItem -Filter CopyForBuild* -Include *.bat,*.cmd -Exclude *.old.cmd,*.old.bat -Recurse

Filtern mit einem regulären Ausdruck:

Get-ChildItem -Path "V:\Myfolder" -Recurse
| Where-Object { $_.Name -match '\ACopyForBuild\.[(bat)|(cmd)]\Z' }
MovGP0
quelle
1
Sollte es nicht sein '\ACopyForBuild\.(bat|cmd)\Z'?
E. Sundin
1

Um die Antwort zu @ user3303020 hinzuzufügen und die Suchergebnisse in eine Datei auszugeben, können Sie sie ausführen

Get-ChildItem V:\MyFolder -name -recurse *.CopyForbuild.bat > path_to_results_filename.txt

Auf diese Weise kann es einfacher sein, nach der richtigen Datei zu suchen.

Gwen Au
quelle