![Powershell-Befehl in Batchdatei: Alle Zeilen aus Textdatei entfernen außer Zeilen mit „foo“ und „bar“?](https://rvso.com/image/1654781/Powershell-Befehl%20in%20Batchdatei%3A%20Alle%20Zeilen%20aus%20Textdatei%20entfernen%20au%C3%9Fer%20Zeilen%20mit%20%E2%80%9Efoo%E2%80%9C%20und%20%E2%80%9Ebar%E2%80%9C%3F.png)
Ich habe eine Textdatei mit diesen 3 Zeilen:
This line contains foo.
This line contains bar.
This line has neither.
Ich kann den folgenden Befehl in einer „.bat“-Datei ausführen (neben der obigen „.txt“-Datei) und er entfernt alle Zeilen in der Textdatei außer den Zeilen, die „foo“ enthalten:
Powershell.exe -Command "gci *.txt | foreach { (cat $_.FullName | ? { $_ -like '*foo*' }) | set-content $_.FullName}"
Wenn Sie das ausführen, hat das den gewünschten Effekt und in der Textdatei bleibt nur diese Zeile übrig:
This line contains foo.
Nun zum Problem: Was ist, wenn ich Zeilen behalten möchte, die "foo" enthalten?Und"Bar" in der Zeile?
Ich habe bisher wahrscheinlich 40 oder 50 verschiedene Kombinationen ausprobiert, ein Pipe-Zeichen gesetzt:, *foo*|*bar*
die Sternchen entfernt foo|bar
, Sternchen nur am Anfang und am Ende gesetzt:, *foo|bar*
ein Komma verwendet, kein Komma verwendet, ein Semikolon verwendet, kein Semikolon verwendet, den -like
Befehl mit und ohne dupliziert $_
und vieles mehr.
Nichts funktioniert – bei jedem Versuch bisher sah die Textdatei immer gleich aus, wobei die ursprünglichen drei Zeilen foo (Zeile 1), bar (Zeile 2) und none (Zeile 3) enthielten.
Um sicherzustellen, dass ich den Befehl nicht bearbeite und dabei einen Fehler mache, lösche ich in regelmäßigen Abständen meine Änderungen und führe den Befehl erneut aus, um nur die Zeilen ohne „foo“ zu entfernen. Dann funktioniert es. Oder ich füge den Befehl einfach erneut ein, teste ihn erneut und versuche dann, ihn so zu bearbeiten, dass er „bar“ einschließt. Allerdings ohne Erfolg.
Ich habe diese Frage vor Kurzem schon einmal gestellt, aber ich glaube, meine Formulierung des Titels war nicht klar. Jemand hat versucht, sie zu beantworten, aber keine der Antworten hat funktioniert, zumindest nicht, wenn ich den Befehl in eine Batchdatei einfüge und ihn neben der Textdatei ausführe. Vielleicht funktioniert es bei ihnen, wenn sie eine andere Methode verwenden als ich, ich weiß es nicht.
Bitte beachten Sie, dass ich einen Powershell-Befehl in einer Batchdatei verwende!Ich tippe nicht in eine Konsole und verwende keine PS1-Skripte. Ich muss nichts davon tun, denn der allererste Befehl, den ich oben erwähnt habefunktioniertum alle Zeilen mit „foo“ zu entfernen.
Da dies offensichtlich funktioniert, kann der Befehl als Grundlage für Erweiterungen verwendet werden, sodass er „foo“ und „bar“ in einem Befehl verarbeiten kann.
Sofern dies nicht natürlich hundertprozentig unmöglich ist – was ich nach etwa vier Tagen, in denen ich 40 oder 50 verschiedene Variationen des Befehls ausprobiert habe, allmählich vermute!
Wenn jemand darauf antwortet, posten Sie bitte einen Batchdateibefehl, so wie ich ihn oben beschrieben habe. Bitte sagen Sie mir nicht, dass ich auf PS1-Skripte umsteigen soll, und geben Sie mir keine Antworten, die erklären, was ich in ein Konsolenfenster eingeben soll.
Der Befehl, den ich oben gepostet habe, muss einfach irgendwie ergänzt werden, sodass „bar“ zu „foo“ hinzugefügt werden kann und somit mehr als eine Textzeichenfolge verarbeitet werden kann.
Der Grund, warum das so schwierig ist, scheint zu sein, dass, wenn Sie einen Befehl ausführen, um alle Zeilen außer denen mit „foo“ zu entfernen, Sie bereits Zeilen mit „bar“ entfernt haben. Ich vermute, das ist der Grund, warum noch niemand eine funktionierende Lösung gefunden hat und vielleicht gibt es einfach keine.
Vielen Dank im Voraus an alle, die eine funktionierende Antwort haben. Normalerweise werden diese Dinge hier sehr schnell beantwortet, oder ich probiere einfach verschiedene Wege aus und es klappt - aber dieses Mal nicht, das ist aus irgendeinem Grund eine wirklich schwierige Frage.
Antwort1
Verwenden Sie einfach zwei separate Bedingungen, die mit ODER verknüpft sind:
cat $_.FullName | ? { $_ -like '*foo*' -or $_ -like '*bar*' }
Klammern können zur besseren Verdeutlichung verwendet werden, sind aber optional:
{ ($_ -like '*foo*') -or ($_ -like '*bar*') }
posten Sie einen Batchdateibefehl, genau wie ich ihn oben beschrieben habe. Bitte sagen Sie mir nicht, dass ich auf PS1-Skripte umsteigen soll, und geben Sie mir keine Antworten, die erklären, was ich in ein Konsolenfenster eingeben soll.
Das ist buchstäblich dasselbe. Es spielt keine Rolle, wie Sie ein PowerShell-Skript aufrufen – ob es in einer Datei gespeichert ist, über die Befehlszeile übergeben oder per Tastatur eingegeben wird, es ist immer noch ein PowerShell-Skript und es folgt denselben Syntaxregeln.
Antwort2
Sie können stattdessen Folgendes verwenden select-string
, das reguläre Ausdrücke akzeptiert:
gci *.txt | % { (cat $_.FullName | select-string -pattern 'foo|bar') | set-content $_.FullName -Force }
select-string
ermöglicht Ihnen, bei Bedarf künftig kompliziertere reguläre Ausdrucksübereinstimmungen durchzuführen.