Ik wil een bestand regel voor regel lezen in PowerShell. Ik wil met name door het bestand lopen, elke regel in een variabele in de lus opslaan en wat bewerkingen op de regel uitvoeren.
Ik ken het Bash-equivalent:
while read line do
if [[ $line =~ $regex ]]; then
# work here
fi
done < file.txt
Niet veel documentatie over PowerShell-lussen.
Antwoord 1, autoriteit 100%
Niet veel documentatie over PowerShell-lussen.
Documentatie over lussen in PowerShell is overvloedig, en misschien wilt u de volgende Help-onderwerpen bekijken: about_For
, about_ForEach
, about_Do
, about_While
.
foreach($line in Get-Content .\file.txt) {
if($line -match $regex){
# Work here
}
}
Een andere idiomatische PowerShell-oplossing voor uw probleem is om de regels van het tekstbestand te pipen naar de ForEach-Object
cmdlet:
Get-Content .\file.txt | ForEach-Object {
if($_ -match $regex){
# Work here
}
}
In plaats van regex-overeenkomsten in de lus, kunt u de regels door Where-Object
om alleen die te filteren waarin u geïnteresseerd bent:
Get-Content .\file.txt | Where-Object {$_ -match $regex} | ForEach-Object {
# Work here
}
Antwoord 2, autoriteit 28%
Get-Content
presteert slecht; het probeert het bestand in één keer in het geheugen te lezen.
C# (.NET)-bestandslezer leest elke regel één voor één
Beste prestatie
foreach($line in [System.IO.File]::ReadLines("C:\path\to\file.txt"))
{
$line
}
Of iets minder presterend
[System.IO.File]::ReadLines("C:\path\to\file.txt") | ForEach-Object {
$_
}
De foreach
-instructie zal waarschijnlijk iets sneller zijn dan ForEach-Object
(zie opmerkingen hieronder voor meer informatie).
Antwoord 3, autoriteit 2%
De almachtige switch
werkt hier goed:
'one
two
three' > file
$regex = '^t'
switch -regex -file file {
$regex { "line is $_" }
}
Uitvoer:
line is two
line is three
Antwoord 4
Ik kon een logbestand van 4 GB in ongeveer 50 seconden lezen met het volgende. Je kunt het misschien sneller maken door het dynamisch te laden als een C#-assembly met PowerShell.
[System.IO.StreamReader]$sr = [System.IO.File]::Open($file, [System.IO.FileMode]::Open)
while (-not $sr.EndOfStream){
$line = $sr.ReadLine()
}
$sr.Close()