Powershell equivalente de `grep -r -l` (--files-with-match)

45

En Powershell, ¿cómo enumero todos los archivos en un directorio (recursivamente) que contienen texto que coincide con una expresión regular dada? Los archivos en cuestión contienen líneas realmente largas de texto incomprensible, por lo que no quiero ver la línea correspondiente, solo el nombre del archivo.

Michael Kropat
fuente

Respuestas:

57

Puede usar Select-Stringpara buscar texto dentro de archivos y Select-Objectpara devolver propiedades específicas para cada coincidencia. Algo como esto:

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

O una versión más corta, usando alias:

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

Si desea solo los nombres de archivo, no las rutas completas, reemplace Pathcon Filename.


Explicación:

  1. Get-ChildItem-Recurse *.* devuelve todos los archivos en el directorio actual y todos sus subdirectorios.

  2. Select-String-Pattern "foobar" busca en esos archivos el patrón dado "foobar".

  3. Select-Object-Unique Pathsolo devuelve la ruta del archivo para cada coincidencia; El -Uniqueparámetro elimina duplicados.

Indrek
fuente
select -Unique... genial, aprendí algo nuevo. Eso funciona perfectamente, gracias!
Michael Kropat
Es . realmente necesitado? Get-ChildItem -Recurse funciona exactamente igual, creo.
Piotr Perak
1
o aún más concisamente, gci -r | sls "foobar" | select -unique path
David Markle
Si no hay coincidencias, PowerShell parece "bloquearse", no volverá. ¿Cómo se sabe cuando se realiza la búsqueda si no hay coincidencias?
reggaeguitar
2

Tenga en cuenta que en powershell v1.0 y v2.0 necesita especificar el primer parámetro de posición (ruta) para trabajar con -Recursion

documentación de technet

-Recurse

Obtiene los elementos en las ubicaciones especificadas y en todos los elementos secundarios de las ubicaciones.

En Windows PowerShell 2.0 y versiones anteriores de Windows PowerShell, el parámetro Recurse funciona solo cuando el valor del parámetro Path es un contenedor que tiene elementos secundarios, como C: \ Windows o C: \ Windows *, y no cuando es un El elemento no tiene elementos secundarios, como C: \ Windows * .exe.

Vladislav
fuente
0

Select-String tiene un -Listparámetro para este propósito:

Devuelve solo la primera coincidencia en cada archivo de entrada. Por defecto, Select-String devuelve un objeto MatchInfo para cada coincidencia encontrada.

- ss64.com

Puedes usarlo así:

gci -Recurse | sls -List FOOBAR

Así es como se ven algunos resultados de muestra (buscando el 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 desea recuperar los FileInfoobjetos reales (en lugar de la ruta relativa y el resultado de una sola coincidencia), puede usarlo así:

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