Powershell-Äquivalent von `grep -r -l` (--files-with-matches)

44

Wie liste ich in Powershell alle Dateien in einem Verzeichnis (rekursiv) auf, die Text enthalten, der einer bestimmten Regex entspricht? Die fraglichen Dateien enthalten sehr lange Zeilen mit unverständlichem Text, daher möchte ich nicht die übereinstimmende Zeile sehen - nur den Dateinamen.

Michael Kropat
quelle

Antworten:

56

Mit können Sie Select-Stringnach Text in Dateien suchen und Select-Objectbestimmte Eigenschaften für jede Übereinstimmung zurückgeben. Etwas wie das:

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

Oder eine kürzere Version, die Aliase verwendet:

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

Wenn Sie nur die Dateinamen und nicht die vollständigen Pfade verwenden möchten, ersetzen Sie diese Pathdurch Filename.


Erläuterung:

  1. Get-ChildItem-Recurse *.* Gibt alle Dateien im aktuellen Verzeichnis und allen seinen Unterverzeichnissen zurück.

  2. Select-String-Pattern "foobar" durchsucht diese Dateien nach dem vorgegebenen Muster "foobar".

  3. Select-Object-Unique Pathgibt nur den Dateipfad für jede Übereinstimmung zurück; Der -UniqueParameter eliminiert Duplikate.

Indrek
quelle
select -Unique... cool, etwas Neues gelernt. Das funktioniert perfekt, danke!
Michael Kropat
Ist . wirklich gebraucht? Get-ChildItem -Recurse funktioniert genau so, wie ich denke.
Piotr Perak
1
oder noch prägnanter gci -r | sls "foobar" | select -unique path
David Markle
Wenn es keine Übereinstimmungen gibt, scheint PowerShell zu "hängen", es wird nicht zurückgegeben. Woher weiß man, wann die Suche abgeschlossen ist, wenn es keine Übereinstimmungen gibt?
Reggaeguitar
2

Beachten Sie, dass Sie in Powershell v1.0 und v2.0 den ersten Positionsparameter (Pfad) angeben müssen, mit dem gearbeitet werden soll -Recursion

Technet-Dokumentation

-Recurse

Ruft die Elemente an den angegebenen Speicherorten und in allen untergeordneten Elementen der Speicherorte ab.

In Windows PowerShell 2.0 und früheren Versionen von Windows PowerShell funktioniert der Recurse-Parameter nur, wenn der Wert des Path-Parameters ein Container ist, der untergeordnete Elemente enthält, z. B. C: \ Windows oder C: \ Windows * item hat keine untergeordneten Elemente, z. B. C: \ Windows * .exe.

Vladislav
quelle
0

Select-String hat einen -ListParameter für diesen Zweck:

Gibt nur die erste Übereinstimmung in jeder Eingabedatei zurück. Standardmäßig gibt Select-String für jede gefundene Übereinstimmung ein MatchInfo-Objekt zurück.

- ss64.com

Du kannst es so benutzen:

gci -Recurse | sls -List FOOBAR

So sehen einige Beispielergebnisse aus (nach denen im Windows SDK gesucht wird 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)

Wenn Sie die tatsächlichen FileInfoObjekte zurückholen möchten (anstelle des relativen Pfads und eines einzelnen Übereinstimmungsergebnisses), können Sie dies folgendermaßen verwenden:

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