432 votes

Comment rechercher une chaîne de caractères dans plusieurs fichiers et renvoyer les noms des fichiers en Powershell?

J'ai commencé à apprendre PowerShell il y a quelques jours, et je n'ai rien trouvé sur google qui fasse ce dont j'ai besoin, donc s'il vous plaît supportez ma question.

On m'a demandé de remplacer certains les chaînes de texte dans plusieurs fichiers. Je ne connais pas nécessairement l'extension des fichiers cibles potentiels et je ne connais pas non plus leur emplacement. Jusqu'à présent, j'ai réussi à parcourir récursivement le répertoire (get-ChildItem -recurse) et à trouver la chaîne que je cherchais avec get-content et select-string :

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy"

Le problème est que je peux voir les occurrences du texte que je recherche, mais je ne sais pas comment dire à PS de retourner le chemin et le nom de chaque fichier correspondant également.

Comment puis-je obtenir le nom et l'emplacement des fichiers contenant l'expression que je recherche ?

3 votes

Peut-être modifier la question pour la rendre plus générique. La réponse à cette question n'a rien à voir avec JBoss ou votre application sur laquelle vous travaillez, il semble...

9 votes

Je viens de repérer votre commentaire et j'ai modifié ma question... 2 ans plus tard ! Mieux vaut tard que jamais.. :)

689voto

jon Z Points 6226

Cela devrait donner l'emplacement des fichiers qui contiennent votre motif :

Get-ChildItem -Recurse | Select-String "dummy" -List | Select Path

3 votes

Que se passe-t-il si vous voulez également déplacer ces fichiers?... Je reçois une erreur avec cela où je ne peux pas ajouter un | Move-Item à la fin de cela.

6 votes

Déplacez-Item n'a pas de paramètre name. Essayez d'ajouter | %{Move-Item $_.name }

57 votes

Get-ChildItem -Recurse | Select-String "dummy" -List | Select Path ne renvoie que le premier correspondance pour chaque fichier donc peut être un peu plus efficace et évite le besoin de les regrouper

107voto

Michael Sorens Points 9637

Il y a une variété de réponses précises ici, mais voici le code le plus concis pour plusieurs variations différentes. Pour chaque variation, la ligne supérieure montre la syntaxe complète et la ligne inférieure montre la syntaxe concise.

L'élément (2) est une forme plus concise des réponses de Jon Z et manojlds, tandis que l'élément (1) est équivalent aux réponses de vikas368 et buygrush.

  1. Liste des objets FileInfo pour tous les fichiers contenant le motif :

    Get-ChildItem -Recurse filespec | Where-Object { Select-String pattern $_ -Quiet }
    ls -r filespec | ? { sls pattern $_ -q }
  2. Liste des noms de fichiers pour tous les fichiers contenant le motif :

    Get-ChildItem -Recurse filespec | Select-String pattern | Select-Object -Unique Path
    ls -r filespec | sls pattern | select -u Path
  3. Liste des objets FileInfo pour tous les fichiers ne contenant pas le motif :

    Get-ChildItem -Recurse filespec | Where-Object { !(Select-String pattern $_ -Quiet) }
    ls -r filespec | ? { !(sls pattern $_ -q) }
  4. Liste des noms de fichiers pour tous les fichiers ne contenant pas le motif :

    (Get-ChildItem -Recurse filespec | Where-Object { !(Select-String pattern $_ -Quiet) }).FullName
    (ls -r filespec | ? { !(sls pattern $_ -q) }).FullName

1 votes

Aussi, si vous cherchez simplement des fichiers qui contiennent le motif n'importe où, vous pouvez abandonner après avoir trouvé la première instance en utilisant le paramètre -List de Select-String

2 votes

Je souhaite que l'OP ait posé une légère variation de la question afin que cela soit l'AA. #1 était très utile et il est évident que @Michael Sorens groks PS!

18voto

manojlds Points 96599

Transmettez le contenu de votre

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy"

à fl *

Vous verrez que le chemin est déjà renvoyé en tant que propriété des objets.

Si vous voulez juste le chemin, utilisez sélectionnez chemin ou sélectionnez -unique chemin pour supprimer les doublons:

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy" | select -unique path

1 votes

Merci à vous deux, c'est exactement ce que je recherche. Malheureusement, lorsque de nombreux sous-répertoires sont impliqués dans le chemin, alors PS coupe le chemin absolu et ajoute trois points à la fin de la ligne comme \dir1\dir2\dir3\chemin... donc je ne sais pas quel fichier est retourné. Y a-t-il un moyen de dire à PS d'être moins gourmand en caractères et de montrer le chemin complet ? :) Merci beaucoup !

3 votes

Il faut ajouter l'interrupteur -File à Get-ChildItem sinon vous vous retrouverez avec une cascade d'erreurs sans fin en essayant d'appeler Get-Content sur des répertoires.

0 votes

Si vous avez besoin du chemin complet, vous pouvez faire ceci (Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy").FullName Les gens semblent oublier que PowerShell est orienté objet; en cas de doute, cherchez une propriété.

9voto

vikas368 Points 150
Get-ChildItem -r | ? {$_.psiscontainer -eq $false} | ? {gc $_.pspath |select-string -pattern "dummy"}

Cela vous donnera tous les détails complets de tous les fichiers.

0 votes

Je ne savais pas du tout que -r fonctionnait. Je pensais que vous deviez toujours faire -Recurse

6voto

buygrush Points 196

Pour conserver tous les détails du fichier complet dans le tableau résultant, vous pourriez utiliser une légère modification de la réponse publiée par vikas368 (qui ne semblait pas fonctionner bien avec l'autocomplétion ISE) :

Obtenir-ChildItem -Recurse | Where-Object { $_ | Select-String -Pattern "dummy" }

ou en abrégé :

ls -r | ?{ $_ | Select-String -Pattern "dummy" }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X