Powershell equivalente a `grep -r -l` (--files-with-correspondências)

44

No Powershell, como listar todos os arquivos em um diretório (recursivamente) que contêm texto que corresponde a um determinado regex? Os arquivos em questão contêm realmente longas linhas de texto incompreensível, por isso não quero ver a linha correspondente - apenas o nome do arquivo.

Michael Kropat
fonte

Respostas:

56

Você pode usar Select-Stringpara procurar texto dentro dos arquivos e Select-Objectretornar propriedades específicas para cada correspondência. Algo assim:

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

Ou uma versão mais curta, usando aliases:

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

Se você deseja apenas os nomes de arquivos, não caminhos completos, substitua Pathpor Filename.


Explicação:

  1. Get-ChildItem-Recurse *.* retorna todos os arquivos no diretório atual e todos os seus subdiretórios.

  2. Select-String-Pattern "foobar" procura nesses arquivos o padrão "foobar" fornecido.

  3. Select-Object-Unique Pathretorna apenas o caminho do arquivo para cada correspondência; o -Uniqueparâmetro elimina duplicatas.

Indrek
fonte
select -Unique... legal, aprendi algo novo. Isso funciona perfeitamente, obrigado!
Michael Kropat
Is . realmente necessário? Get-ChildItem -Recurse funciona exatamente da mesma maneira que eu penso.
Piotr Perak
11
ou ainda mais concisa, gci -r | sls "foobar" | select -unique path
David Markle
Se não houver correspondências, o PowerShell parece "travar", não retornará. Como saber quando é feita a pesquisa se não há correspondências?
reggaeguitar 11/04
2

Observe que no powershell v1.0 e v2.0 você precisa especificar o parâmetro da primeira posição (caminho) para trabalhar com -Recursion

documentação technet

-Recurso

Obtém os itens nos locais especificados e em todos os itens filhos dos locais.

No Windows PowerShell 2.0 e versões anteriores do Windows PowerShell, o parâmetro Recurse funciona apenas quando o valor do parâmetro Path é um contêiner que possui itens filhos, como C: \ Windows ou C: \ Windows *, e não quando é um item não possui itens filhos, como C: \ Windows * .exe.

Vladislav
fonte
0

Select-String possui um -Listparâmetro para esta finalidade:

Retorne apenas a primeira correspondência em cada arquivo de entrada. Por padrão, Select-String retorna um objeto MatchInfo para cada correspondência encontrada.

- ss64.com

Você pode usá-lo assim:

gci -Recurse | sls -List FOOBAR

Veja a aparência de alguns resultados de amostra (pesquisando no Windows SDK 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)

Se você deseja recuperar os FileInfoobjetos reais (em vez do caminho relativo e um único resultado de correspondência), use-o assim:

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