Я хочу читать файл построчно в PowerShell. В частности, я хочу перебрать файл, сохранить каждую строку в переменной в цикле и выполнить некоторую обработку в строке.
Я знаю эквивалент Bash:
while read line do
if [[ $line =~ $regex ]]; then
# work here
fi
done < file.txt
Не так много документации по циклам PowerShell.
powershell
powershell-ise
Kingamere
источник
источник
Get-Content
загружает в память сразу весь файл, что приводит к сбою или зависанию больших файлов.process
блок и выводит в конвейер по одному объекту на строку, то проблема в этой функции. Никакие проблемы с загрузкой полного содержимого в память не по винеGet-Content
.foreach($line in Get-Content .\file.txt)
Он загрузит весь файл в память перед началом итерации. Если вы мне не верите, возьмите файл журнала размером 1 ГБ и попробуйте.Get-Content .\file.txt | ForEach-Object -Process {}
поддерживает конвейер и не загружает весь файл в память. По умолчанию Get-Content будет передавать конвейер по одной строке за раз.Ответы:
Документация на петлях в PowerShell много, и вы можете проверить следующие разделы справки:
about_For
,about_ForEach
,about_Do
,about_While
.Еще одно идиоматическое решение вашей проблемы с помощью PowerShell - передать строки текстового файла
ForEach-Object
командлету :Вместо сопоставления регулярных выражений внутри цикла вы можете пропустить строки
Where-Object
для фильтрации только тех, которые вам интересны:источник
docs.microsoft.com
.Get-Content
имеет плохую производительность; он пытается прочитать файл в память сразу.Читатель файлов C # (.NET) читает каждую строку одну за другой
Лучшее выступление
Или чуть менее производительный
foreach
Заявление, вероятно , будет немного быстрее , чемForEach-Object
(см комментарии ниже для получения дополнительной информации).источник
[System.IO.File]::ReadLines("C:\path\to\file.txt") | ForEach-Object { ... }
.foreach
Заявление будет загружать всю коллекцию объекта .ForEach-Object
использует конвейер для потоковой передачи. Теперьforeach
оператор, вероятно, будет немного быстрее, чемForEach-Object
команда, но это потому, что загрузка всего этого в память обычно происходит быстрее.Get-Content
все же ужасно.foreach()
- это псевдонимForeach-Object
foreach
это утверждение, какif
,for
илиwhile
.ForEach-Object
это команда, напримерGet-ChildItem
. Также существует псевдоним по умолчаниюforeach
forForEach-Object
, но он используется только при наличии конвейера. См. Подробное объяснениеGet-Help about_Foreach
или щелкните ссылку в моем предыдущем комментарии, который ведет ко всей статье Microsoft The Scripting Guys о различиях между оператором и командой.Get-Alias foreach
Foreach-Object
$line
на$_
в блоке сценария цикла.Здесь хорошо работает всемогущий переключатель:
Вывод:
источник