Читать файл построчно в PowerShell
Я хочу прочитать файл построчно в PowerShell. В частности, я хочу пройтись по файлу, сохранить каждую строку в переменной в цикле и выполнить некоторую обработку в строке.
Я знаю эквивалент Bash:
while read line do
if [[ $line =~ $regex ]]; then
# work here
fi
done < file.txt
Не много документации по циклам PowerShell.
6 ответов
Не много документации по циклам PowerShell.
Документация по циклам в PowerShell обильна, и вы можете проверить следующие разделы справки: about_For
, about_ForEach
, about_Do
, about_While
,
foreach($line in Get-Content .\file.txt) {
if($line -match $regex){
# Work here
}
}
Другое идиоматическое решение PowerShell для вашей проблемы - это передача строк текстового файла в ForEach-Object
командлет:
Get-Content .\file.txt | ForEach-Object {
if($_ -match $regex){
# Work here
}
}
Вместо сопоставления регулярных выражений в цикле, вы можете передать линии через Where-Object
отфильтровать только те, которые вас интересуют:
Get-Content .\file.txt | Where-Object {$_ -match $regex} | ForEach-Object {
# Work here
}
Get-Content
имеет плохую производительность; он пытается прочитать файл в память все сразу.
C# (.NET) программа для чтения файлов читает каждую строку одну за другой
Лучший спектакль
foreach($line in [System.IO.File]::ReadLines("C:\path\to\file.txt"))
{
$line
}
Или же
[System.IO.File]::ReadLines("C:\path\to\file.txt") | ForEach-Object {
$_
}
foreach
утверждение, вероятно, будет немного быстрее, чем ForEach-Object
, но это потому, что загрузка всего этого в память обычно происходит быстрее.
Я смог прочитать файл журнала размером 4 ГБ примерно за 50 секунд со следующим. Вы можете сделать это быстрее, загрузив его как сборку C# динамически с помощью PowerShell.
[System.IO.StreamReader]$sr = [System.IO.File]::Open($file, [System.IO.FileMode]::Open)
while (-not $sr.EndOfStream){
$line = $sr.ReadLine()
}
$sr.Close()
Здесь хорошо работает всемогущий переключатель:
'one
two
three' > file
$regex = '^t'
switch -regex -file file {
$regex { "line is $_" }
}
Выход:
line is two
line is three
Set-Location 'C:\files'
$files = Get-ChildItem -Name -Include *.txt
foreach($file in $files){
Write-Host("Start Reading file: " + $file)
foreach($line in Get-Content $file){
Write-Host($line)
}
Write-Host("End Reading file: " + $file)
}
По умолчанию Get-Content считывает все строки в текстовом файле и создает массив в качестве его вывода с каждой строкой текста в качестве элемента в этом массиве. В этом случае индексный номер массива равен номеру строки текстового файла, Таким образом, мы можем получить каждую строку txt-файла, используя индексный номер массива.
Вы можете зациклить массив для чтения каждой строки.
$ TxtContent = Get-content -Path "C: \ path \ TestFile.txt"
$ TxtContent 1
$ TxtContent [2]
[См. Это для полного примера]: http://dotnet-helpers.com/powershell-demo/reading-from-text-files-with-powershell/