|
|
|
@ -0,0 +1,252 @@
|
|
|
|
|
# Get-Content - открываем и читаем файл
|
|
|
|
|
|
|
|
|
|
Для открытия файлов и чтения его содержимого используется команда Powershell `Get-Content`.
|
|
|
|
|
|
|
|
|
|
## Получение данных
|
|
|
|
|
|
|
|
|
|
### Открытие 1 файла
|
|
|
|
|
|
|
|
|
|
Для открытия файла 'C:\text.txt' можно использовать следующую команду:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\text.txt'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Открытие нескольких файлов
|
|
|
|
|
|
|
|
|
|
Можно использовать подстановку. Символы подстановок бывают следующих типов:
|
|
|
|
|
|
|
|
|
|
- '*' - говорит об неизвестном количестве символов;
|
|
|
|
|
- [a,b] - говорит, что в этом месте может быть буква 'a' или 'b';
|
|
|
|
|
- ? - обозначает один неизвестный символ.
|
|
|
|
|
|
|
|
|
|
Каждый из символов выше можно применять вместе и неограниченное число раз, в любой части пути и имени.
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\Windows\System32\drivers\etc\*st*'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Следующие примеры вернут аналогичный результат:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\Windows\System32\drivers\etc\[l,h]*ost*'
|
|
|
|
|
Get-Content -Path 'C:\Windows\System32\drivers\etc\*h?st*'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Кроме символов подстановки, можно использовать параметры фильтрации:
|
|
|
|
|
|
|
|
|
|
- Include - в этом параметре мы добавляем шаблон, по которому будем включать файл;
|
|
|
|
|
- Exclude - с помощью этого параметра исключает файлы;
|
|
|
|
|
- Filter - исключает результаты.
|
|
|
|
|
|
|
|
|
|
Для каждого из этих параметров есть обязательно условие - использовать знак '*' в конце пути.
|
|
|
|
|
|
|
|
|
|
Так мы вернем все файлы с расширением '.txt':
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\*' -Filter '*.txt'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
В отличие от Filter, в Include и Exclude мы можем использовать несколько значений. В этом примере мы откроем файлы формата '.txt' и '.ini':
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\*' -Include '*.txt','*.ini'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Полное и построчное чтение с поиском
|
|
|
|
|
|
|
|
|
|
По умолчанию, если мы будем передавать результат команды через конвейер Powershell вывод будет построчный. Это может составить проблему, так как при дополнительных условиях у нас будет возвращаться одна строка, а не весь текст:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\file*.txt' | Select-String -Pattern 'Line 8'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Что бы текст передавался полностью, а не построчно - используйте параметр Raw:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\file*.txt' -Raw | Select-String -Pattern 'Line 8'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Если вам вдруг понадобится выводить по 2 или более строк за раз, можно указать их количество через ReadCount:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\file*.txt' -ReadCount 2 | Select-String -Pattern 'Line 8'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Разделение файла
|
|
|
|
|
|
|
|
|
|
Файл выводится построчно из-за делиметра (разделителя), который по умолчанию равен '\n' (идентификатор новой строки). Мы можем разделить файл иначе, например, использовав точку с запятой:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\delimiter.txt' -Delimiter ';'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
То есть результат выше - это массив. В массивах Powershell мы можем получать содержимое по индексам. В следующем примере я просто уберу точку с запятой:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
$content = Get-Content -Path 'C:\delimiter.txt' -Delimiter ';'
|
|
|
|
|
# Выведем первый элемент
|
|
|
|
|
$content[0]
|
|
|
|
|
# Уберем разделитель во всех адресах
|
|
|
|
|
foreach ($c in $content){
|
|
|
|
|
$c -replace ';',''
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Подсчет количества строк
|
|
|
|
|
|
|
|
|
|
Построчный вывод с командой Powershell позволяет посчитать количество строк во всем файле. Для подсчета используется команда Measure-Object:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\file.txt' | measure
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Если нужна только цифра, а не объект, можно сделать так:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
(Get-Content -Path 'C:\file.txt' | measure).Count
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Кодировки
|
|
|
|
|
|
|
|
|
|
В параметре -Encoding можно указать следующие кодировки:
|
|
|
|
|
|
|
|
|
|
- ASCII
|
|
|
|
|
- BigEndianUnicode
|
|
|
|
|
- BigEndianUTF32
|
|
|
|
|
- Byte
|
|
|
|
|
- Default
|
|
|
|
|
- OEM
|
|
|
|
|
- Unicode
|
|
|
|
|
- UTF7
|
|
|
|
|
- UTF8
|
|
|
|
|
- UTF32
|
|
|
|
|
|
|
|
|
|
## Чтения файла под другим пользователем
|
|
|
|
|
|
|
|
|
|
В этом командлете не предусмотрена возможность открытия файла под другим пользователем. При любых попытках вы будете получать ошибки:
|
|
|
|
|
|
|
|
|
|
- Access to the path is denied
|
|
|
|
|
- The FileSystem provider supports credentials only on the New-PSDrive cmdlet. Perform the operation again withoutspecifying credentials.
|
|
|
|
|
|
|
|
|
|
Для обхода этих ошибок, если у вас нет другого выхода, нужно использовать `Invoke-Command` (команда удаленного подключения).
|
|
|
|
|
|
|
|
|
|
Сам процесс открытия файла под другим пользователем будет выглядеть так:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
# Вводим свои учетные данные
|
|
|
|
|
$creds = Get-Credential
|
|
|
|
|
# Выполняем запрос под другим пользователем
|
|
|
|
|
Invoke-Command -Computer localhost -Credential $creds -ScriptBlock {Get-Content -Path 'C:\Folder\File2.txt'}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Непрерывное чтение
|
|
|
|
|
С помощью параметра Wait вы можете читать файл, который в этот момент обновляется системой или другим пользователем:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\file1.txt' -Wait
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Ограничение вывода строк
|
|
|
|
|
|
|
|
|
|
Можно ограничить вывод содержимого файла указав количество нужных строк в начале или конце:
|
|
|
|
|
|
|
|
|
|
- Head - выведет указанное количество строк с начала;
|
|
|
|
|
- Tail - выведет указанное количество строк с конца.
|
|
|
|
|
|
|
|
|
|
Так будут выведены только первые 5 строк:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-Content -Path 'C:\file1.txt' -Head 5
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Поиск файлов по содержимому
|
|
|
|
|
|
|
|
|
|
`Get-Content` не позволяет искать и открывать фалы находящиеся внутри других каталогов. Такой поиск называется рекурсивным и он доступен в `Get-ChildItem`.
|
|
|
|
|
|
|
|
|
|
В следующем примере мы вернем файлы из всех каталогов и подкаталогов:
|
|
|
|
|
```powershell
|
|
|
|
|
Get-ChildItem -Path 'C:\Windows\' -Recurse -File
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`File` - возвращает только файлы. Каталоги нам не нужны.
|
|
|
|
|
|
|
|
|
|
С `Get-ChildItem` вы так же можете использовать Include, Exclude и Filter, которые были рассмотрены раннее. Использовать эти ключи лучше всего в первой команде т.к. это будет работать быстрее.
|
|
|
|
|
|
|
|
|
|
Через конвейер мы сможем открыть каждый файл, а с `Select-String` проверить есть ли в нем нужный текст. Так мы найдем файл с Powershell, который содержит строку '127.0.0.1' в папке Windows:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
Get-ChildItem -Path 'C:\Windows\System32\drivers\etc\' -Recurse -File |
|
|
|
|
|
Get-Content -Raw |
|
|
|
|
|
Select-String '127.0.0.1'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Если убрать параметр Raw, то у нас выведется только та строка, которую мы искали:
|
|
|
|
|
|
|
|
|
|
## Изменение файла с последующей записью
|
|
|
|
|
|
|
|
|
|
Вы так же можете изменить содержимое файла и перезаписать этот файл. Представим, что вам нужно заменить адрес '127.0.0.1' в строке - это можно сделать так:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
'My address: 127.0.0.1/24' -replace '127.0.0.1','192.168.3.2'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Или с помощью регулярного выражения (не точный шаблон):
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
'My address: 127.0.0.1/24' -replace '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}','192.168.3.2'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Для записи в файл у нас есть два варианта. Первый - это использовать перенаправление в виде знака '>', который перезапишет все содержимое файла или создаст новый файл:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
$file_content = Get-Content -Path 'C:\file1.txt'
|
|
|
|
|
$file_content -replace '127.0.0.1','192.168.3.2' > file1.txt
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Второй вариант - использовать команду Set-Content:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
$file_content = Get-Content -Path 'C:\file1.txt'
|
|
|
|
|
$file_content -replace '127.0.0.1','192.168.3.2' | Set-Content -Path 'C:\file1.txt'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Подсчет четных чисел в файле
|
|
|
|
|
|
|
|
|
|
У меня есть файл 'file.txt' со следующим содержанием:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
some text 123 some text 6 some
|
|
|
|
|
text 9 some text 312345
|
|
|
|
|
123.2
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Шаблон регулярного выражения `\d*\.?\d*` говорит, что мы ищем число, после которого может быть точка, после которого могут быть еще числа. Таким образом мы захватим целые и числа с плавающей точкой.
|
|
|
|
|
|
|
|
|
|
Для выделения таких чисел из строк нужно использовать Select-String:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
$file = Get-Content -Path 'file.txt'
|
|
|
|
|
$result = Select-String -InputObject $file -Pattern '\d*\.?\d*' -AllMatches | Foreach {$_.matches}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Нам нужно отформатировать вывод убрав пустые строки и получить значения свойства Value:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
$result | where Value -ne '' | select Value
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Мы можем вернуть остаток от деления использовав %. Если число делится на 2 с остатком 0, то оно будет четным:
|
|
|
|
|
```powershell
|
|
|
|
|
# Открываем файл
|
|
|
|
|
$opened_file = Get-Content -Path 'file.txt'
|
|
|
|
|
# Поиск чисел
|
|
|
|
|
$result = Select-String -InputObject $opened_file -Pattern '\d*\.?\d*' -AllMatches | Foreach {$_.matches}
|
|
|
|
|
# Исключение пустых строк в выводе
|
|
|
|
|
$result = ($result | where Value -ne '').Value
|
|
|
|
|
foreach ($num in $result){
|
|
|
|
|
# Результат деления
|
|
|
|
|
$n = $num%2
|
|
|
|
|
if ($n -eq 0){Write-Output "Число четное: $num"}
|
|
|
|
|
else {Write-Output "Число не четное: $num"}
|
|
|
|
|
}
|
|
|
|
|
```
|