Powershell equivalent of `grep -r -l` (--files-with-matches)

47,148

Solution 1

You can use Select-String to search for text inside files, and Select-Object to return specific properties for each match. Something like this:

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

Or a shorter version, using aliases:

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

If you want just the filenames, not full paths, replace Path with Filename.


Explanation:

  1. Get-ChildItem-Recurse *.* returns all files in the current directory and all its subdirectories.

  2. Select-String-Pattern "foobar" searches those files for the given pattern "foobar".

  3. Select-Object-Unique Path returns only the file path for each match; the -Unique parameter eliminates duplicates.

Solution 2

Use the below command inside the directory you would like to perform the "grep" and change [SEARCH_PATTERN] to match what you would like to match. It's recursive, searching through all files in the directory.

dir -Recurse | Select-String - pattern [SEARCH_PATTERN]

http://www.jamescoyle.net/how-to/1205-how-to-use-powershell-to-recursively-search-for-text-within-files-on-windows

Solution 3

Note, that in powershell v1.0 and v2.0 you need to specify first position parameter (path) to work with -Recursion

technet documentation

-Recurse

Gets the items in the specified locations and in all child items of the locations.

In Windows PowerShell 2.0 and earlier versions of Windows PowerShell, the Recurse parameter works only when the value of the Path parameter is a container that has child items, such as C:\Windows or C:\Windows*, and not when it is an item does not have child items, such as C:\Windows*.exe.

Solution 4

Select-String has a -List parameter for this purpose:

Return only the first match in each input file. By default, Select-String returns a MatchInfo object for each match found.

ss64.com

You can use it like this:

gci -Recurse | sls -List FOOBAR

Here's what some sample results look like (searching the Windows SDK for 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)

If you wanted to get back the actual FileInfo objects (instead of the relative Path and a single match result), you might use it like this:

Get-ChildItem -Recurse -File | where { Select-String -Path $_ -List -Pattern FOOBAR }
Share:
47,148

Related videos on Youtube

Michael Kropat
Author by

Michael Kropat

Projects I've published that may interest you: BetterWin32Errors — a better interface to winerror.h dapper-invoice — hours invoice featuring style over substance Is Shell Command ______ Portable? — reference website jumpapp — run-or-raise application switcher for X11 desktops MlkPwgen — secure password generator (.NET + PowerShell) secure-random-password — password generator (JavaScript) sh-realpath — a portable, pure shell implementation of realpath SSLfie — generate self-signed x.509 certificates for SSL/TLS

Updated on September 18, 2022

Comments

  • Michael Kropat
    Michael Kropat over 1 year

    In Powershell, how do I list all files in a directory (recursively) that contain text that matches a given regex? The files in question contain really long lines of incomprehensible text, so I don't want to see the matching line -- just the filename.

  • Michael Kropat
    Michael Kropat about 10 years
    select -Unique... cool, learned something new. That works perfectly, thanks!
  • Piotr Perak
    Piotr Perak almost 10 years
    Is . really needed? Get-ChildItem -Recurse works exactly the same I think.
  • David Markle
    David Markle almost 9 years
    or even more concisely, gci -r | sls "foobar" | select -unique path
  • reggaeguitar
    reggaeguitar about 5 years
    If there's no matches PowerShell seems to "hang", it won't return. How does one know when the search is done if there are no matches?