Équivalent Powershell de `grep -r -l` (--files-with-matches)

45

Dans Powershell, comment répertorier (de manière récursive) tous les fichiers d'un répertoire contenant du texte correspondant à une expression régulière donnée? Les fichiers en question contiennent de très longues lignes de texte incompréhensible. Je ne souhaite donc pas voir la ligne correspondante, mais uniquement le nom du fichier.

Michael Kropat
la source

Réponses:

57

Vous pouvez utiliser Select-Stringpour rechercher du texte dans des fichiers et Select-Objectpour renvoyer des propriétés spécifiques pour chaque correspondance. Quelque chose comme ça:

Get-ChildItem -Recurse *.* | Select-String -Pattern "foobar" | Select-Object -Unique Path

Ou une version plus courte, utilisant des alias:

dir -recurse *.* | sls -pattern "foobar" | select -unique path

Si vous voulez seulement les noms de fichiers, pas les chemins complets, remplacez Pathpar Filename.


Explication:

  1. Get-ChildItem-Recurse *.* renvoie tous les fichiers du répertoire en cours et tous ses sous-répertoires.

  2. Select-String-Pattern "foobar" recherche dans ces fichiers le motif "foobar".

  3. Select-Object-Unique Pathrenvoie uniquement le chemin du fichier pour chaque correspondance; le -Uniqueparamètre élimine les doublons.

Indrek
la source
select -Unique... cool, a appris quelque chose de nouveau. Cela fonctionne parfaitement, merci!
Michael Kropat
Est . vraiment besoin? Get-ChildItem -Recurse fonctionne exactement de la même façon, je pense.
Piotr Perak
1
ou même plus précisément, gci -r | sls "foobar" | select -unique path
David Markle
S'il n'y a pas de correspondance, PowerShell semble "se bloquer", il ne reviendra pas. Comment savoir quand la recherche est faite s'il n'y a pas de correspondance?
Reggaeguitar
2

Notez que, dans powershell v1.0 et v2.0, vous devez spécifier le premier paramètre de position (chemin) avec lequel travailler -Recursion

documentation technique

-Recours

Obtient les éléments dans les emplacements spécifiés et dans tous les éléments enfants des emplacements.

Dans Windows PowerShell 2.0 et les versions antérieures de Windows PowerShell, le paramètre Recurse ne fonctionne que lorsque la valeur du paramètre Path est un conteneur contenant des éléments enfants, tels que C: \ Windows ou C: \ Windows *, et non lorsqu'il s'agit d'un conteneur. L'élément n'a pas d'éléments enfants, tels que C: \ Windows * .exe.

Vladislav
la source
0

Select-String a un -Listparamètre à cet effet:

Renvoie uniquement la première correspondance dans chaque fichier d'entrée. Par défaut, Select-String renvoie un objet MatchInfo pour chaque correspondance trouvée.

- ss64.com

Vous pouvez l'utiliser comme ceci:

gci -Recurse | sls -List FOOBAR

Voici quelques exemples de résultats (recherche dans le SDK de Windows ERROR_SUCCESS):

shared\bthdef.h:576:#define BTH_ERROR(_btStatus)   ((_btStatus) != BTH_ERROR_SUCCESS)
shared\netioapi.h:2254:    ERROR_SUCCESS on success.  WIN32 error code on error.
shared\rpcnterr.h:34:#define RPC_S_OK                          ERROR_SUCCESS
shared\winerror.h:214:// MessageId: ERROR_SUCCESS
um\advpub.h:40://      ERROR_SUCCESS_REBOOT_REQUIRED        Reboot required.
um\bluetoothapis.h:243://      ERROR_SUCCESS
um\ClusApi.h:571:_Success_(return == ERROR_SUCCESS)
um\dsparse.h:102:_Success_(return == ERROR_SUCCESS)
um\eapmethodpeerapis.h:228:// If the function succeeds, it returns ERROR_SUCCESS. Otherwise, it is
um\eappapis.h:56:// If the functions succeed, they return ERROR_SUCCESS. Otherwise, it is
um\MapiUnicodeHelp.h:583:                if ((hkeyPolicy && RegQueryValueExW(hkeyPolicy, szName, 0, &dwType, (LPBYTE)
&dwLcid, &dwSize) == ERROR_SUCCESS && dwType == REG_DWORD) ||
um\Mddefw.h:127:            routine will return ERROR_SUCCESS and the inherited data even if
um\Msi.h:1693:// Returns ERROR_SUCCESS if file is a package.
um\MsiQuery.h:192:// Returns ERROR_SUCCESS if successful, and the view handle is returned,
um\msports.h:46:    ERROR_SUCCESS if the dialog was shown
um\ncryptprotect.h:164:    ERROR_SUCCESS
um\NTMSAPI.h:1761:_Success_ (return == ERROR_SUCCESS)
um\oemupgex.h:108://  Returns:    ERROR_SUCCESS in case of success, win32 error otherwise
um\PatchWiz.h:90://                     ERROR_SUCCESS, plus ERROR_PCW_* that are listed in constants.h.
um\Pdh.h:415:_Success_(return == ERROR_SUCCESS)

Si vous voulez récupérer les FileInfoobjets réels (au lieu du chemin relatif et d'un résultat de correspondance unique), vous pouvez l'utiliser comme ceci:

Get-ChildItem -Recurse -File | where { Select-String -Path $_ -List -Pattern FOOBAR }
Michael Kropat
la source