Wie suche ich eine Zeichenfolge in mehreren Dateien und gebe die Namen der Dateien in Powershell zurück?


303

Ich habe vor ein paar Tagen angefangen, Powershell zu lernen, und ich konnte auf Google nichts finden, was das tut, was ich brauche. Bitte tragen Sie meine Frage.

Ich wurde gebeten, einige Textzeichenfolgen in mehrere Dateien zu ersetzen. Ich kenne nicht unbedingt die Erweiterung der möglichen Zieldateien und ich kenne auch nicht deren Speicherort. Bisher habe ich es geschafft, rekursiv in das Verzeichnis ( get-ChildItem -recurse) zu navigieren und die gesuchte Zeichenfolge mit get-content und select-string zu finden:

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy"

Das Problem ist, dass ich das Vorkommen des gesuchten Textes sehen kann, aber ich weiß nicht, wie ich PS anweisen soll, den Pfad und den Namen für jede übereinstimmende Datei zurückzugeben.

Wie kann ich den Namen und den Speicherort der Dateien ermitteln, die den gesuchten Ausdruck enthalten?


2
Bearbeiten Sie die Frage möglicherweise allgemeiner. Die Antwort auf diese Frage hat nichts mit JBoss oder Ihrer Anwendung zu tun, an der Sie arbeiten. Es scheint ...
Kolob Canyon

5
Ich habe gerade Ihren Kommentar entdeckt und meine Frage bearbeitet ... 2 Jahre später! besser spät als nie .. :)
Bluz

Antworten:


469

Dies sollte den Speicherort der Dateien angeben, die Ihr Muster enthalten:

Get-ChildItem -Recurse | Select-String "dummy" -List | Select Path

3
Was ist, wenn Sie diese Dateien auch verschieben möchten? ... Ich erhalte eine Fehlermeldung, bei der ich keinem | beitreten kann Move-Item an das Ende davon.
Rud3y

6
Move-Item hat keinen nameParameter. Versuchen Sie hinzuzufügen| %{Move-Item $_.name <destination>}
Jon Z

49
Get-ChildItem -Recurse | Select-String "dummy" -List | Select PathGibt nur die erste Übereinstimmung für jede Datei zurück, ist also möglicherweise etwas effizienter und vermeidet die Notwendigkeit, sie zu gruppieren
ben

5
Es ist erwähnenswert, dass Sie nur nach einem bestimmten Dateityp filtern können, z. B. nach txtDateien, wenn Sie Get-ChildItem -Recurse -Filter *.txtstattdessen verwenden
Girardi

@ rud3y Ich empfehle dringend, dass Sie es in einem Skript mit einer foreachSchleife schreiben, wenn Sie große Operationen wie diese ausführen. Es wird sehr kompliziert, wenn Sie versuchen, all das in einer Zeile zu tun, und es ist sehr leicht, einen großen Fehler zu machen. Ich spreche aus Erfahrung
Kolob Canyon

75

Hier gibt es eine Vielzahl genauer Antworten, aber hier ist der prägnanteste Code für verschiedene Variationen. Für jede Variation zeigt die obere Zeile die vollständige Syntax und die untere die knappe Syntax.

Punkt (2) ist eine präzisere Form der Antworten von Jon Z und manojlds, während Punkt (1) den Antworten von vikas368 und buygrush entspricht.

  1. Listen Sie FileInfo- Objekte für alle Dateien auf, die Muster enthalten:

    Get-ChildItem -Recurse filespec | Where-Object { Select-String pattern $_ -Quiet }
    ls -r filespec | ? { sls pattern $_ -q }
    
  2. Listen Sie Dateinamen für alle Dateien auf, die Muster enthalten:

    Get-ChildItem -Recurse filespec | Select-String pattern | Select-Object -Unique Path
    ls -r filespec | sls pattern | select -u Path
    
  3. Listen Sie FileInfo- Objekte für alle Dateien auf, die kein Muster enthalten:

    Get-ChildItem -Recurse filespec | Where-Object { !(Select-String pattern $_ -Quiet) }
    ls -r filespec | ? { !(sls pattern $_ -q) }
    
  4. Listen Sie Dateinamen für alle Dateien auf, die kein Muster enthalten:

    (Get-ChildItem -Recurse filespec | Where-Object { !(Select-String pattern $_ -Quiet) }).FullName
    (ls -r filespec | ? { !(sls pattern $_ -q) }).FullName
    

Wenn Sie nur nach Dateien suchen, die das Muster irgendwo enthalten, können Sie aufgeben, nachdem Sie die erste Instanz gefunden haben, indem Sie den -ListParameterSelect-String
KyleMit

Ich wünschte, das OP hätte eine geringfügige Änderung der Frage gestellt, damit dies die AA wäre. # 1 war sehr nützlich und es ist offensichtlich, dass @Michael Sorens PS schimpft!
cBlaine

20

Dadurch werden der Pfad, der Dateiname und die gefundene Inhaltszeile angezeigt, die dem Muster entsprechen.

Get-ChildItem -Path d:\applications\*config -recurse |  Select-String -Pattern "dummy" 

Wenn nur eine Zeile zwischen den Ergebnissen hinzugefügt werden könnte :)
Cladelpino

15

Pipe den Inhalt von Ihrem

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy"

zu fl *

Sie werden sehen, dass der Pfad bereits als Eigenschaft der Objekte zurückgegeben wird.

Wenn Sie nur den Pfad möchten, verwenden select pathoder select -unique pathentfernen Sie Duplikate:

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy" | select -unique path

1
Dank euch beiden ist dies genau das, wonach ich suche. Wenn der Pfad viele Unterverzeichnisse enthält, schneidet PS leider den absoluten Pfad ab und fügt am Ende der Zeile drei Punkte hinzu, z. B. \ dir1 \ dir2 \ dir3 \ path. Ich weiß also nicht, welche Datei zurückgegeben wird . Gibt es eine Möglichkeit, PS zu sagen, dass sie weniger gierig auf Charaktere ist und sich die Mühe macht, den vollständigen Pfad anzuzeigen? :) Vielen Dank !
Bluz

3
Sie müssen den -FileSchalter hinzufügen, sonst kommt es zu Get-ChildItemeiner nie endenden Fehlerkaskade , wenn Sie versuchen, Get-ContentVerzeichnisse aufzurufen .
RubberDuck

Wenn Sie den vollständigen Pfad benötigen, können Sie dies tun. Die (Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy").FullNameLeute scheinen zu vergessen, dass PowerShell objektorientiert ist. Wenn Sie Zweifel haben, suchen Sie nach einer Immobilie
Kolob Canyon

10

So würde ich es machen, du brauchst keinen Get-Content:

ls -r | Select-String dummy | select line,path

oder

ls -r | Select-String dummy | fl *

Um zu sehen, was die verschiedenen Eigenschaften sind ...

Das geht schneller. Das zweite Argument ist -filter:

ls -r . *.bat | select-string netsh

2
+1, Dies funktioniert perfekt für meinen Fall, jedoch select Pattern, LineNumber, Filenamefür eine präzisere Ausgabe. Zeile gibt ALLES in der Zeile zurück, die Ihre Musterzeichenfolge enthält. Sie können dies auch einfach auf eine CSV ausgeben, wenn Sie möchten.
Protonova

9
Get-ChildItem -r | ? {$_.psiscontainer -eq $false} | ? {gc $_.pspath |select-string -pattern "dummy"}

Dadurch erhalten Sie alle Details aller Dateien


Ich wusste überhaupt nicht, dass das -rfunktioniert. Ich dachte, du musst es immer tun-Recurse
Kolob Canyon

5

Um die vollständigen Dateidetails im resultierenden Array beizubehalten, können Sie eine geringfügige Änderung der Antwort von vikas368 verwenden (die mit der automatischen Vervollständigung von ISE nicht gut zu funktionieren schien):

Get-ChildItem -Recurse | Where-Object { $_ | Select-String -Pattern "dummy" }

oder kurz:

ls -r | ?{ $_ | Select-String -Pattern "dummy" }

5

Wenn Sie in einem Verzeichnis suchen, können Sie dies tun:

select-string -Path "c:\temp\*.*" -Pattern "result"  -List | select Path

4

Daraufhin wird eine Liste des vollständigen Pfads zu jeder Datei angezeigt, die die Suchzeichenfolge enthält:

foreach ($file in Get-ChildItem | Select-String -pattern "dummy" | Select-Object -Unique path) {$file.path}

Beachten Sie, dass keine Überschrift über den Ergebnissen und keine Textzeilen mit der Suchzeichenfolge angezeigt werden. Sie erfahren lediglich, wo Sie die Dateien finden, die die Zeichenfolge enthalten.


2
Haben Sie eine Idee, wie die Zeilennummer, in der das Muster gefunden wurde, zusammen mit dem Dateinamen angezeigt wird?
Piotr L

4

Ich habe eine der obigen Antworten geändert, um ein bisschen mehr Informationen zu erhalten. Dies ersparte mir später eine zweite Frage. Es war ungefähr so:

Get-ChildItem `
        -Path "C:\data\path" -Filter "Example*.dat" -recurse | `
    Select-String -pattern "dummy" | `
    Select-Object -Property Path,LineNumber,Line | `
    Export-CSV "C:\ResultFile.csv"

Ich kann den Pfad und die Datei-Platzhalter mit diesen Strukturen angeben und es speichert den Dateinamen, die Zeilennummer und die relevante Zeile in einer Ausgabedatei.


Cool! Vielen Dank für diese zusätzliche Lösung :) Könnten Sie jedoch bitte auf die Antwort verlinken, auf der Ihre Lösung basiert, und den Autor dieser Antwort benennen, um die Gutschrift zu geben? Vielen Dank!
Max Vollmer
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.