Как использовать PowerShell Get-Content для чтения файла
Cmdlet Get-Content может быть использован для получения содержимого из файла в PowerShell. Он будет извлекать содержимое построчно, сохраняя его в массиве. Это позволяет вам использовать или обрабатывать каждую строку в вашем скрипте PowerShell.
Get-Content имеет несколько параметров, которые позволяют вам выбирать или фильтровать результаты, которые вы хотите получить из файла. И когда вам нужно обработать множество больших файлов, используя параметр -raw, вы можете ускорить процесс.
В этой статье мы рассмотрим, как использовать командлет Get-Content и объясним различные параметры, которые мы можем использовать.
Читать файл с помощью Get-Content
Мы собираемся начать с основ, читать файл в PowerShell построчно, используя командлет Get-Content. Для приведенных ниже примеров я буду использовать текстовый файл с 100 строками, которые пронумерованы. Это упрощает следование примерам:
1..100 | ForEach-Object { Add-Content -Path .\LineNumbers.txt -Value "This is line $_." }Приведённый выше код принадлежит Microsoft и создаёт текстовый файл, в котором каждая строка начинается со строки «Это строка », за которой следует номер строки:
Чтобы просмотреть результаты вновь созданного файла, мы можем использовать командлет Get-Content. Вам нужно только указать путь к файлу, чтобы начать читать его содержимое:
Get-Content -Path .\LineNumbers.txtЕсли мы сохраним результат Get-Content в переменной, то мы увидим, что PowerShell хранит результаты в массиве. Это означает, что мы можем использовать любую функцию массива на результатах или обрабатывать каждую строку с помощью цикла ForEach:
$contents = Get-Content -Path .\LineNumbers.txt
$contents.GetType()
Result
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
Return the 6th line (the index of an array start at 0 😉 )
$contents[5]
Result
This is line 6Возврат первых или последних x строк
По умолчанию cmdlet Get-Content вернет все содержимое файла в PowerShell. Но в некоторых случаях вы можете захотеть просмотреть только первые или последние x строк из файла. Например, при отладке проблемы вам часто нужны только последние несколько строк из файла журнала.
Для этого у нас есть два варианта: мы можем использовать параметр -TotalCount, который возвращает первые x элементов содержимого. Либо мы можем использовать параметр -Tail, который возвращает последние x элементов файла.
Итак, давайте вернемся к нашему примеру с лог-файлом. Мы хотим просмотреть последние 10 строк из лога. Для этого нам нужно указать путь и добавить -Tail 10, чтобы вернуть только последние 10 строк:
Get-Content C:\temp\files\la-srv-dc01.log -Tail 10Чтобы прочитать первые x элементов из файла, нам потребуется использовать параметр -TotalCount:
Get-Content -Path .\LineNumbers.txt -TotalCount 5Вернуть одну строку из файла
Если вы знаете, какая конкретно строка вам нужна из текстового файла, то можно выбрать только одну строку из текстового файла. Как мы знаем, результаты хранятся в массиве. Поэтому мы можем использовать индекс массива, чтобы выбрать необходимый номер строки.
Имейте в виду, что индекс массива начинается с 0, поэтому, если мы хотим вернуть строку 16, нам нужно указать номер индекса 15. Мы оборачиваем команду Get-Content в круглые скобки ( ), чтобы PowerShell сначала завершил команду Get-Content, прежде чем продолжить.
(Get-Content -Path .\LineNumbers.txt)[15]
Result
This is line 16.Если у вас есть большой текстовый файл, возможно, вы не захотите читать его полностью только для того, чтобы вернуть одну строку. Вы можете выбрать только первые или последние x строк из файла, а затем выбрать номер строки, используя индекс массива.
Например, предположим, что нам нужна пятая строка из файла. Мы устанавливаем TotalCount на 5, читая только первые 5 строк, и возвращаем последний элемент из массива:
(Get-Content -Path .\LineNumbers.txt -TotalCount 5)[-1]
Result
This is line 5.Чтение нескольких файлов с помощью Get-Content
Также возможно прочитать содержимое нескольких файлов одновременно с помощью Get-Content в PowerShell. Для этого вам только нужно указать путь, где расположены файлы, за которым следует звездочка *.
Get-Content -Path c:\temp\files\*Имейте в виду, что в результатах не будет никаких ссылок на исходные файлы. Вы не сможете узнать, из какого файла взята строка x.
Мы также можем отфильтровать, какие файлы мы хотим прочитать. Например, если вы хотите получить содержимое всех файлов .log, вы можете добавить параметр -Filter к этому:
Get-Content -Path c:\temp\files\* -Filter '*.log'Используя -Raw
Команда Get-Content считывает каждую строку файла в массив, что отлично, когда вам нужно обрабатывать каждую строку независимо или вы ищете одну строку. Но массив ужасен, если вам нужно выполнить поиск и замену в содержимом файла.
Например, когда у вас есть HTML-файл, который вы используете в качестве шаблона для электронного письма, которое вы собираетесь отправить с помощью PowerShell. В HTML-файле у нас есть заполнители, которые нам нужно заменить, например, так:
<p>Hi {{manager.firstname}},</p>
<p>
The account for {{user.fullname}} is ready. Below you will find the login details for {{user.firstname}}. We have set a temporary password which must be
changed after the first login.
</p>
<p>
In the attachment you will find a starting guide for new users
</p>Вместо того, чтобы проходить по каждой строке в поисках заполнителей и заменять их, мы можем использовать параметр -Raw, чтобы считать весь файл как одну строку и использовать оператор -Replace для замены заполнителей:
(Get-Content -Path c:\temp\template.html -Raw) -replace '{{user.fullname}}', $user.fullName -replace '{{user.firstname}}', $user.givenNameЕще одно преимущество использования параметра -Raw заключается в том, что он работает намного быстрее. Get-Content отлично справляется с маленькими текстовыми файлами, но когда вам нужно обрабатывать большие текстовые файлы, вы, вероятно, заметите, что команда работает немного медленно.
Например, текстовый файл размером 50 Мб читается почти за 5 секунд, как вы можете видеть на скриншоте ниже:
Но при использовании -Raw это заняло менее полусекунды:
Если вам все еще нужны результаты в массиве, то мы можем использовать -Raw в сочетании с оператором строки -split, чтобы создать массив из каждой строки файла. Этот метод все еще в 5 раз быстрее, чем использование Get-Content без -Raw.
$log = (Get-Content .\largefile.log -Raw) -split "`r`n"Чтение файлов быстрее с помощью ReadAllLines
При обработке очень больших файлов, размером 100 Мб и более, существует еще более быстрый метод чтения содержимого файла с помощью PowerShell. Метод .Net System.IO.File.ReadAllLines() будет считывать все строки в память вдвое быстрее по сравнению с использованием метода -Raw.
Результаты, как и в случае с Get-Content, сохраняются в массиве. Поэтому вы можете обрабатывать эти данные таким же образом.
$log = [System.IO.File]::ReadAllLines('c:\temp\files\largefile.log')Вы также можете использовать метод [System.IO.File]::ReadLines, который даже быстрее. Но это сразу же выведет содержимое в консоль, вместо его хранения в памяти. Проблема этого метода заключается в том, что вам нужно будет закрыть файл после завершения, иначе он будет заблокирован потоком.
Следите за файлами с помощью -Wait
Последняя интересная функция Get-Contents заключается в том, что мы можем отслеживать или контролировать содержимое файла, используя параметр -Wait. Если вы, например, хотите следить за файлом журнала, то вместо того чтобы каждый раз заново запускать командлет Get-Content, вы можете добавить параметр -wait.
Как только содержимое файла будет обновлено (и сохранено), это обновит вывод Get-Content.
Get-Content -Path c:\temp\testfiles\LineNumbers.txt -Tail 5 -Wait
Result
This is line 96.
This is line 97.
This is line 98.
This is line 99.
This is line 100.Если мы добавим новые строки в конец файла, то они появятся в результатах.
Заключение
Командлет Get-Content в PowerShell отлично подходит, когда нужно быстро прочитать файл. Но при работе с большими файлами вам действительно нужно использовать параметр -Raw, по крайней мере, чтобы ускорить процесс. Кроме того, попробуйте метод .Net, вы будете поражены, насколько он быстрый.
Я надеюсь, что вы нашли эту статью полезной. Если у вас есть какие-либо вопросы, просто оставьте комментарий ниже.




