PowerShell Suche nach 2 unterschiedlichen Strings in Text Dateien

Art Vandelay

Lieutenant
Registriert
Apr. 2020
Beiträge
802
Hallo Leute,

ich bin auf der Suche nach einer Optimierung für meinen Workflow.
Ich muss für den Job häufig in vorliegenden Text Dateien nach bestimmten Strings suchen. Das können pro Tag gerne mal 10.000 Dateien sein.

Kein Problem:
Code:
Select-string -pattern "TEXT1" -path c:\dir1\*.txt
Die Ausgabe sind dann alle Text Dateien mit Namen und dem gesuchten Inhalt "TEXT1"

Nun suche ich jedoch in dieser Ergebnismenge nach einem String "TEXT2", da ich dies mit select-string nicht verketten kann, kopiere ich mir die Ergebnismenge aus dem obigen code in ein Temp Verzeichnis und suche dann in einem zweiten Suchlauf in diesen Dateien nach meinem "TEXT2" String
Code:
Select-string -pattern "TEXT1" -path c:\dir1\*.txt | copy-item -destination c:\tmpdir1
Select-string -pattern "TEXT2" -path c:\tmpdir1\*.txt

Mein Ansatz um dies zu optimieren wäre statt select-string, get-content zu benutzen. Das hier funktioniert und bringt mir einen ähnlichen output wie oben (nur leider ohne Dateinamen):
Code:
get-content -path  c:\dir1\*.txt | where {$_ -match "TEXT1"}

Nun die Idee hier beide Abfragen zu kombinieren
Code:
get-content -path  c:\dir1\*.txt | where {$_ -match "TEXT1" -and $_ -match "TEXT2"}
Nur hier ist die Ausgabe immer leer, obwohl es definitiv Dateien mit beiden Strings gibt.

Denke ich falsch, oder was könnte ich noch tun um meine Suche in einer Abfrage zu erfüllen?

Viele Grüße :)
 
Bin nur am Handy aber kannst dir das Ergebnis aus Text1 nicht in eine variable packen und die noch mal „durchsuchen“? 🤷🏻‍♂️
 
Btw: Bei mir funktioniert der Befehl - aber ich erhalte halt den Inhalt, nicht den Dateinamen.

Wie sehen TEXT1 und TEXT2 konkret aus? Sind da evtl irgendwelche Regex-spezifischen Zeichen enthalten?


Edit
Hier die zweite Antwort sollte doch eigentlich das tun:
https://stackoverflow.com/questions...tring-to-find-more-than-one-pattern-in-a-file

Edit2:
Das hier liefert bei mir die Datei(en):
Code:
Get-ChildItem *.txt |
  where { $_ | Select-String -Pattern 'TEXT1' } |
  where { $_ | Select-String -Pattern 'TEXT2' } |
  Write-Output
 
  • Gefällt mir
Reaktionen: Art Vandelay, derlorenz und br3adwhale
Wie wärs hiermit:
PowerShell:
Select-String -Pattern "TEXT1" -Path c:\dir1\*.txt | Select-String -Pattern "TEXT2"
 
  • Gefällt mir
Reaktionen: tollertyp
Danke für eure schnellen Antworten und das mitdenken :-)

Das hier ist die Lösung, da muss man erst mal drauf kommen:

tollertyp schrieb:
Edit2:
Das hier liefert bei mir die Datei(en):
Code:
Get-ChildItem *.txt |
  where { $_ | Select-String -Pattern 'TEXT1' } |
  where { $_ | Select-String -Pattern 'TEXT2' } |
  Write-Output

Dieser Konstrukt bringt als Ausgabe nur die gefilterten Dateien, ohne den gefilterten Inhalt, aber das ist in meinem Fall genau richtig, da ich die Dateinamen brauche.
Danke! :-)
Ergänzung ()

Korben2206 schrieb:
Wie wärs hiermit:
PowerShell:
Select-String -Pattern "TEXT1" -Path c:\dir1\*.txt | Select-String -Pattern "TEXT2"

Diese Verkettung kann nicht funktionieren, da die Ausgabe des ersten Select-string schon nur noch den Dateinamen mit dem gefilterten String "TEXT1" liefert, und da kann kein select-string auf TEXT2 mehr funktionieren.
 
hast recht :) Funktioniert nicht. Hab n Denkfehler drin gehabt:)
Ergänzung ()

Aber.... folgendes sollte (auch) gehen:

PowerShell:
Select-String -Pattern "TEXT1" -Path "C:\dir1\*.txt" |  % { Select-String -Pattern "TEXT2" -Path "C:\dir1\$($_.Filename)" }

:)
 
Zuletzt bearbeitet:
Ich hab's grade noch mal getestet, die Lösung mit Get-childitem | where {$_ | select-string ...} | where {$_ | select-string ...} funktioniert bei mir mit Version 5.1, nutze das im ConEmu Programm.

Alternativ auch mal mit Version 7.1.3 getestet, da komme ich mit den verketteten select-string ... | select-string ... leider auch nicht zum Ziel. Wäre Syntaxtechnisch natürlich deutlich einfacher, teste es aber gerne auch noch mal mit der neusten PWSH Version.
 
@Art Vandelay hatte einen Denkfehler, bzw. ein schlechtes Beispiel zum testen genommen und den code auf den du dich vermutlich beziehst gelöscht (bad style, sry). Oben der Code sollte aber gehen :)
 
Korben2206 schrieb:
Aber.... folgendes sollte (auch) gehen:

PowerShell:
Select-String -Pattern "TEXT1" -Path "C:\dir1\*.txt" |  % { Select-String -Pattern "TEXT2" -Path "C:\dir1\$($_.Filename)" }

Der funktioniert in der Tat. Aber was da $($_.filename) macht, leuchtet mir grade noch nicht ein.
 
Art Vandelay schrieb:
Der funktioniert in der Tat. Aber was da $($_.filename macht, leuchtet mir grade noch nicht ein.
Select-String liefert nicht einfach einen String zurück, sondern ein Objekt. Das hat unter anderem die Eigenschaft Filename in der der Dateiname gespeichert ist. :)
 
okay geschnallt. Wäre für den täglichen Einsatz tatsächlich schneller und praktikabler wie die get-childitem Lösung von oben. Cool, ich werde mir beide Varianten speichern! :-)
 
Ich nutze übrigens nicht mehr ConEmu direkt, sondern Cmder. Und den integriert ins Windows Terminal.
Hatte aber glaubt auf der alten WIndows PowerShell getestet, nicht auf der neuen.

1666286272178.png

Ich teste auch mal wieder da...

Edit: Ja funktioniert bei mir auch unter der PowerShell 7.2.6
 
Ich nutze conemu für 4 gesplittete Sessions in einem Fenster, hatte ich damals mal hier erfragt.
Da ich in der Regel nur auf Server Betriebssystemen unterwegs bin, wo an Windows Terminal gar nicht zu denken ist, ist das für mich auch die perfekte Lösung. Unabhängig davon, dass Windows Terminal mir außer der Tab Funktion kaum Mehrwert bietet.
Aber habe durch den Talk gestern mal die PWSH 7.2.6 ins Conemu eingebunden und läuft super. Auch hier habe ich bisher in der Version 7.2.6 kaum Mehrwert gesehen gegenüber der Onboard Version 5.0, eher im Gegenteil, Zugriff auf Eventlogs waren mir glaube ich nicht möglich wenn ich mich recht erinnere.
 
Zurück
Oben