Recherche récursive de fichiers à l'aide de PowerShell


238

Je recherche un fichier dans tous les dossiers.

Copyforbuild.bat est disponible dans de nombreux endroits, et je voudrais effectuer une recherche récursive.

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

Comment puis-je le faire dans PowerShell?

Réponses:


393

Utilisez l' applet de commande Get-ChildItem avec le -Recursecommutateur:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force

1
Semble avoir un problème que s'il s'exécute dans un répertoire auquel vous n'êtes pas autorisé à accéder, la recherche entière est abandonnée car le processus se termine. Y a-t-il un moyen de contourner cela?
deed02392

6
Essayez de définir le paramètre ErrorAction sur Continue ou SilentlyContinue (au cas où sa valeur ne serait pas celle mentionnée).
Shay Levy

22
Une façon plus courte de faire exactement la même chose: cd V:\MyFoldersuivie parls -r -inc CopyForBuild.bat
Orion Edwards

8
Donc ce que les commentateurs ci-dessus signifient est ...ls -r -ea silentlycontinue -fo -inc "filename.txt" | % { $_.fullname }
Andrew

J'ai adapté cette réponse pour faire une chaîne partielle en ajoutant le symbole astrique ( *) à la fin du nom de fichier. ****** LINE1: $File = "Microsoft.OData.Core.NetFX35.V7*"LIGNE2: $Folder = "C:\Program Files"LIGNE3:Get-ChildItem -Path $Folder -Filter $File -Recurse -ErrorAction SilentlyContinue -Force
SherlockSpreadsheets

37

J'utilise ceci pour rechercher des fichiers et puis PowerShell affiche le chemin complet des résultats:

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

Vous pouvez toujours utiliser le caractère générique *dans le FolderNameet / ou FileName.fileExtension. Par exemple:

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

L'exemple ci-dessus recherchera n'importe quel dossier du C:\lecteur commençant par le mot Folder. Donc, si vous avez un dossier nommé FolderFooet FolderBarPowerShell affichera les résultats de ces deux dossiers.

Il en va de même pour le nom de fichier et l'extension de fichier. Si vous souhaitez rechercher un fichier avec une certaine extension, mais ne connaissez pas le nom du fichier, vous pouvez utiliser:

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

Ou vice versa:

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

4
Je trouve cette réponse extrêmement utile car elle aborde un cas d'utilisation particulier - souhaitant réellement utiliser le fichier que vous recherchez. Le | pour vous donner le nom complet du fichier est quelque chose qui manque dans les autres réponses.
Développeur Newteq

1
Je dois être d'accord avec @ Sanity1123 ici, si vous voulez réellement utiliser le fichier, vous aurez besoin du chemin d'accès complet au fichier. À mon humble avis, cela devrait être la réponse acceptée.
uceumern

31

Lorsque vous recherchez des dossiers où vous pourriez obtenir une erreur basée sur la sécurité (par exemple C:\Users), utilisez la commande suivante:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force

12
Get-ChildItem V:\MyFolder -name -recurse *.CopyForbuild.bat

Fonctionnera également


Et si vous voulez sortir les résultats dans un fichier, vous pouvez ajouter `> path_to_filename.txt` à la fin de la commande.
Gwen Au

7

Voici la méthode que j'ai finalement trouvée après avoir eu du mal:

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

Pour rendre la sortie plus propre (uniquement chemin), utilisez:

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

Pour obtenir uniquement le premier résultat, utilisez:

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

Maintenant, pour les choses importantes:

Pour rechercher uniquement les fichiers / répertoires ne pas utiliser -Fileou -Directory(voir ci - dessous pourquoi). Utilisez-le à la place pour les fichiers:

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

et supprimez les -eq $falserépertoires for. Ne laissez pas de caractère générique de fin comme bin/*.

Pourquoi ne pas utiliser les commutateurs intégrés? Ils sont terribles et suppriment des fonctionnalités au hasard. Par exemple, pour utiliser -Includeavec un fichier, vous devez terminer le chemin avec un caractère générique. Cependant, cela désactive le -Recursecommutateur sans vous dire:

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

Vous penseriez que cela vous donnerait tous les *.libs dans tous les sous-répertoires, mais cela ne fera que rechercher le niveau supérieur de bin.

Pour rechercher des répertoires, vous pouvez utiliser -Directory, mais vous devez ensuite supprimer le caractère générique de fin. Pour une raison quelconque, cela ne se désactivera pas -Recurse. C'est pour ces raisons que je recommande de ne pas utiliser les drapeaux intégrés.

Vous pouvez raccourcir considérablement cette commande:

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

devient

gci './path*/' -s -Include 'name*' | where {$_.PSIsContainer -eq $false}
  • Get-ChildItem est aliasé à gci
  • -Path est par défaut à la position 0, vous pouvez donc simplement créer le premier chemin d'argument
  • -Recurse est aliasé à -s
  • -Include n'a pas de sténographie
  • Utilisez des guillemets simples pour les espaces dans les noms / chemins, afin de pouvoir entourer la commande entière de guillemets doubles et de l'utiliser dans l'invite de commandes. Faire l'inverse (entourer de guillemets simples) provoque des erreurs

6

Essaye ça:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse | Where-Object { $_.Attributes -ne "Directory"}

2
Vous pouvez également utiliser | Where-Object { !$_PSIsContainer }pour exclure des dossiers
Gargravarr

5

Filtrer à l'aide de caractères génériques:

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

Filtrage à l'aide d'une expression régulière:

Get-ChildItem -Path "V:\Myfolder" -Recurse
| Where-Object { $_.Name -match '\ACopyForBuild\.[(bat)|(cmd)]\Z' }

1
N'est-ce pas '\ACopyForBuild\.(bat|cmd)\Z'?
E. Sundin

1

Pour ajouter à la réponse @ user3303020 et sortir les résultats de la recherche dans un fichier, vous pouvez exécuter

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

Il peut être plus facile de rechercher le bon fichier de cette façon.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.