Ich möchte eine Datei Zeile für Zeile in PowerShell lesen. Insbesondere möchte ich die Datei durchlaufen, jede Zeile in einer Variablen in der Schleife speichern und einige Verarbeitungen in der Zeile durchführen.
Ich kenne das Bash-Äquivalent:
while read line do
if [[ $line =~ $regex ]]; then
# work here
fi
done < file.txt
Nicht viel Dokumentation zu PowerShell-Schleifen.
powershell
powershell-ise
Kingamere
quelle
quelle
Get-Content
Lädt die gesamte Datei auf einmal in den Speicher, was bei großen Dateien fehlschlägt oder einfriert.process
Block angibt und pro Zeile ein anderes Objekt in die Pipeline ausspuckt, ist diese Funktion das Problem. Probleme beim Laden des gesamten Inhalts in den Speicher sind nicht die Schuld vonGet-Content
.foreach($line in Get-Content .\file.txt)
Es wird die gesamte Datei in den Speicher geladen, bevor die Iteration beginnt. Wenn Sie mir nicht glauben, holen Sie sich eine 1-GB-Protokolldatei und probieren Sie es aus.Get-Content .\file.txt | ForEach-Object -Process {}
ist Pipeline-fähig und lädt nicht die gesamte Datei in den Speicher. Standardmäßig durchläuft Get-Content jeweils eine Zeile durch die Pipeline.Antworten:
Dokumentation über Schleifen in Powershell ist reichlich vorhanden, und Sie können die folgenden Hilfethemen prüfen wollen:
about_For
,about_ForEach
,about_Do
,about_While
.Eine andere idiomatische PowerShell-Lösung für Ihr Problem besteht darin, die Zeilen der Textdatei an das
ForEach-Object
Cmdlet weiterzuleiten :Anstatt den regulären Ausdruck innerhalb der Schleife abzugleichen, können Sie die Zeilen durchleiten
Where-Object
, um nur die zu filtern, an denen Sie interessiert sind:quelle
docs.microsoft.com
.Get-Content
hat schlechte Leistung; Es wird versucht, die Datei auf einmal in den Speicher einzulesen.Der C # (.NET) -Dateireader liest jede Zeile einzeln
Beste Leistung
Oder etwas weniger performant
Die
foreach
Aussage wird wahrscheinlich etwas schneller sein alsForEach-Object
(siehe Kommentare unten für weitere Informationen).quelle
[System.IO.File]::ReadLines("C:\path\to\file.txt") | ForEach-Object { ... }
. Dieforeach
Anweisung lädt die gesamte Sammlung in ein Objekt .ForEach-Object
verwendet eine Pipeline zum Streamen. Jetzt ist dieforeach
Anweisung wahrscheinlich etwas schneller als derForEach-Object
Befehl, aber das liegt daran, dass das Laden des Ganzen in den Speicher normalerweise schneller ist.Get-Content
ist jedoch immer noch schrecklich.foreach()
ist ein Alias vonForeach-Object
foreach
ist eine Aussage, wieif
,for
oderwhile
.ForEach-Object
ist ein Befehl, wieGet-ChildItem
. Es gibt auch einen Standardalias vonforeach
forForEach-Object
, der jedoch nur verwendet wird, wenn eine Pipeline vorhanden ist. Lesen Sie die lange Erklärung inGet-Help about_Foreach
oder klicken Sie auf den Link in meinem vorherigen Kommentar, der zu einem ganzen Artikel von Microsoft's The Scripting Guys über die Unterschiede zwischen der Anweisung und dem Befehl führt.Get-Alias foreach
=>Foreach-Object
, aber Sie haben Recht, es gibt Unterschiede$line
um$_
in der Script - Block-Schleife.Der allmächtige Schalter funktioniert hier gut:
Ausgabe:
quelle