2015-11-04 20 views
20

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 eine Verarbeitung in der Zeile vornehmen.Datei Zeile für Zeile in PowerShell lesen

Ich kenne die Bash-Äquivalent:

while read line do 
    if [[ $line =~ $regex ]]; then 
      # work here 
    fi 
done < file.txt 

Nicht viel Dokumentation über Powershell-Schleifen.

Antwort

40

Es gibt nicht viel Dokumentation zu PowerShell-Schleifen.

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.

foreach($line in Get-Content .\file.txt) { 
    if($line -match $regex){ 
     # Work here 
    } 
} 

Eine weitere idiomatische Powershell Lösung für Ihr Problem ist die Zeilen der Textdatei auf dem ForEach-Object cmdlet zu Rohr:

Get-Content .\file.txt | ForEach-Object { 
    if($_ -match $regex){ 
     # Work here 
    } 
} 

Statt Regex Matching innerhalb der Schleife, Sie Rohr konnten die Linien durch Where-Object, um nur diejenigen zu filtern, die Sie interessieren:

+0

Die Links sind nicht gebrochen, aber sie jetzt 'docs.microsoft.com' umleiten. –

+0

'Get-Content' ist wirklich schlecht, wenn Sie versuchen, große Dateien zu lesen –

+1

@KolobCanyon absolut wahr :-) können Sie eine separate Antwort über die Leistungskosten bei Größe/Skala hinzufügen –

8

Get-Content hat schlechte Leistung; Es versucht, die Datei auf einmal in den Speicher zu lesen.

C# (.NET) Dateileser liest jede Zeile einzeln

foreach($line in [System.IO.File]::ReadLines("C:\path\to\file.txt")) 
{ 
     $line 
} 
+0

Ich würde wahrscheinlich '[System.IO.File] :: ReadLines (" C: \ path \ to \ file.txt ") | ForEach-Objekt {...} '. Die 'foreach'-Anweisung lädt [die gesamte Sammlung in ein Objekt] (https://blogs.technet.microsoft.com/heyscriptingguy/2014/07/08/getting-to-know-forecha-forefox-object/). 'ForEach-Object' verwendet eine Pipeline zum Streamen mit. Jetzt ist die 'foreach'-Anweisung wahrscheinlich etwas schneller als der 'ForEach-Object'-Befehl, aber das liegt daran, dass das Laden des gesamten Objekts in den Speicher normalerweise schneller ist. 'Get-Content' ist jedoch immer noch schrecklich. –

+0

@BaconBits 'foreach()' ist ein Alias ​​von 'Foreach-Object' –

+5

Das ist ein sehr häufiges Missverständnis. 'foreach' ist eine Aussage wie' if', 'for' oder' while'. 'ForEach-Object' ist ein Befehl wie' Get-ChildItem'. Für 'ForEach-Object' gibt es auch einen Standard-Alias' foreach', der jedoch nur bei einer Pipeline verwendet wird. Siehe die ausführliche Erklärung in "Get-Help about_Foreach" oder klicke auf den Link in meinem vorherigen Kommentar, der auf einen ganzen Artikel von The Scripting Guys von Microsoft über die Unterschiede zwischen der Anweisung und dem Befehl verweist. –