Парсим, редактируем, экспортируем: JSON, XML и CSV в PowerShell
Привет, Хабр!
Сегодня рассмотрим, как в PowerShell работать с форматами данных JSON, XML и CSV. Эти форматы часто используются для обмена информацией между системами, и умение быстро парсить, изменять и генерировать данные в них — одна из важных задач в автоматизации и интеграции.
JSON
Парсинг JSON в объекты PowerShell
В PowerShell есть мощный способ для преобразования JSON-строк в объекты PowerShell с помощью командлета ConvertFrom-Json
.
Пример:
$jsonString = @"
{
"Name": "Ivan",
"Age": 32,
"Skills": ["PowerShell", "Python", "Bash"],
"Address": {
"Street": "Lenina 1",
"City": "Moscow",
"ZipCode": "123456"
}
}
"@
# Преобразование JSON в объект PowerShell
$jsonObject = $jsonString | ConvertFrom-Json
# Доступ к данным
Write-Host "Имя: $($jsonObject.Name)"
Write-Host "Первый навык: $($jsonObject.Skills[0])"
Write-Host "Город: $($jsonObject.Address.City)"
Но не всё так просто, как может показаться. Важно учитывать глубину данных и использовать параметр -Depth
, когда работаешь с более сложными структурами. По дефолту ConvertFrom-Json
обрабатывает только три уровня вложенности.
Пример:
$jsonString = @"
{
"Company": {
"Departments": [
{
"Name": "IT",
"Employees": [
{"Name": "Ivan", "Role": "SysAdmin"},
{"Name": "Sara", "Role": "DevOps"}
]
}
]
}
}
"@
$jsonObject = $jsonString | ConvertFrom-Json -Depth 5
Write-Host $jsonObject.Company.Departments[0].Employees[1].Name
Здесь -Depth 5
позволяет получить доступ к глубоко вложенным данным.
Манипуляция JSON-данными
Пора манипулировать данными
В PowerShell естьAdd-Member
для добавления новых полей в объект. Пример ниже добавляет новое свойство в JSON-объект:
$jsonObject | Add-Member -MemberType NoteProperty -Name "Email" -Value "[email protected]"
Write-Host $jsonObject
После выполнения этой команды объект будет содержать новое свойство Email
.
Для изменения значения свойства достаточно просто присвоить новое значение свойству:
$jsonObject.Name = "Sasha"
Write-Host $jsonObject.Name
Ты изменишь свойство Name
, и объект автоматом обновится.
Удалить свойство из объекта можно с помощью метода Remove()
:
$jsonObject.PSObject.Properties.Remove("Email")
Write-Host $jsonObject
Генерация JSON из объектов PowerShell
Когда приходит время конвертировать объекты PowerShell обратно в JSON для передачи данных, на помощь приходит ConvertTo-Json
. Этот командлет превращает объект в строку формата JSON, готовую к использованию.
Пример:
$process = Get-Process | Select-Object -First 1
$json = $process | ConvertTo-Json
Write-Host $json
Этот код создает JSON, представляющий информацию о первом процессе, запущенном на твоей системе.
P.S:
Для обработки больших JSON-файлов стоит использовать потоковую обработку данных, избегая загрузки всего файла в память.
XML
Парсинг XML в PowerShell
Первое, что нужно знать о работе с XML в PowerShell — синтаксис [xml]
, который превращает XML-данные в объекты, с которыми можно легко работать.
Пример:
[xml]$xmlData = Get-Content -Path "C:\config.xml"
Write-Host $xmlData.Configuration.AppSettings.Setting[0].Key
Здесь мы читаем XML-файл с помощью Get-Content
и приводим его к объекту XML с помощью [xml]
. После этого доступ к элементам можно получить так же, как и к свойствам объектов PowerShell.
XPath для работы с большими XML-файлами:
Когда речь идет о больших XML-файлах, стоит использовать более мощные инструменты для выборки данных. В этом случае хорош XPATH. PowerShell поддерживает работу с XPath через командлет Select-Xml
, который позволяет выполнять запросы к XML-документам.
Пример:
$xmlFile = "C:\config.xml"
$xpathQuery = "//Setting[@Key='AppMode']"
$result = Select-Xml -Path $xmlFile -XPath $xpathQuery
# Доступ к результату
Write-Host $result.Node.InnerText
Здесь мы выполняем запрос XPath для поиска элемента с атрибутом Key
, равным AppMode
.
Манипуляция XML-данными
Теперь пора поговорить о том, как изменять эти данные. В PowerShell добавление, изменение и удаление элементов XML — это несложная задача. Для этого есть методы CreateElement
, SetAttribute
, и AppendChild
.
Пример добавления нового элемента:
# Создаем новый элемент
$newElement = $xmlData.CreateElement("NewSetting")
$newElement.SetAttribute("Key", "NewFeature")
$newElement.InnerText = "Enabled"
# Добавляем его в существующую структуру
$xmlData.Configuration.AppSettings.AppendChild($newElement)
# Сохраняем изменения
$xmlData.Save("C:\config.xml")
Мы создали новый элемент с атрибутом и значением, а затем добавили его в раздел настроек. Манипуляция объектами XML через методы, такие как CreateElement
, SetAttribute
, и AppendChild
.
Изменение существующего элемента:
$xmlData.Configuration.AppSettings.Setting[0].InnerText = "Production"
$xmlData.Save("C:\config.xml")
Простое присваивание нового значения существующему элементу меняет его содержимое. После изменения не забудь сохранить файл с помощью метода Save
.
Валидация XML-данных с помощью XSD
Валидация XML по схеме XSD помогает убедиться, что данные соответствуют требуемому формату.
Для валидации XML сначала нужно загрузить XSD-схему, затем применить её к XML-данным.
# Загрузка XML и XSD
[xml]$xmlData = Get-Content -Path "C:\config.xml"
$schemaSet = New-Object System.Xml.Schema.XmlSchemaSet
$schemaSet.Add("", "C:\schema.xsd")
# Настройка валидации
$xmlData.Schemas.Add($schemaSet)
$xmlData.Validate({
param ($sender, $e)
Write-Host "Ошибка валидации: $($e.Message)"
})
Этот код загружает XSD-схему и валидирует XML-данные. В случае несоответствия схемы выводится ошибка.
CSV
Импорт CSV в PowerShell
Начнем с самого простого — импорта CSV. В PowerShell для этого используется командлет Import-Csv
, который автоматом преобразует строки CSV в объекты PowerShell. Каждый столбец файла CSV становится свойством объекта.
Пример импорта CSV:
$employees = Import-Csv -Path "C:\data\employees.csv"
После этой команды Import-Csv
преобразует каждую строку файла CSV в объект PSCustomObject
, где заголовки файла становятся именами свойств. Теперь можно обращаться к данным как к объектам PowerShell:
$employees[0].FirstName
Работа с файлами без заголовков:
Бывает, что CSV-файл не содержит заголовков. В таком случае PowerShell создаст заголовки автоматически (Column1, Column2 и т.д.), но это бывает редко удобно. Чтобы задать собственные заголовки, можно использовать параметр -Header
:
$employees = Import-Csv -Path "C:\data\employees.csv" -Header "FirstName", "LastName", "Department"
Настройка разделителей:
По дефолту PowerShell ожидает, что разделителем в CSV будет запятая. Но не всегда в CSV используются запятые — бывают и табы, точки с запятой и другие символы. Для указания другого разделителя есть параметр -Delimiter
:
$employees = Import-Csv -Path "C:\data\employees.tsv" -Delimiter "`t" # для табуляции
Манипуляция данными в формате CSV
Командлет Where-Object
позволяет фильтровать строки CSV на основе условий:
$itEmployees = $employees | Where-Object { $_.Department -eq "IT" }
Здесь мы отфильтровали всех сотрудников из IT-отдела. Строки можно фильтровать по любому свойству объекта, используя любые логические операторы.
Сортировка данных производится с помощью Sort-Object
.
$sortedEmployees = $employees | Sort-Object LastName
PowerShell позволяет изменять данные. Например, если нужно изменить департамент всех сотрудников с фамилией «Smith»:
$employees | ForEach-Object {
if ($_.LastName -eq "Smith") {
$_.Department = "HR"
}
}
Этот подход позволяет гибко изменять данные прямо в памяти, что особенно удобно при обработке больших CSV-файлов.
Экспорт данных в CSV
Когда все изменения внесены, возникает необходимость сохранить данные в CSV. Для этого используется командлет Export-Csv
, который преобразует объекты обратно в строки CSV и сохраняет их в файл.
$employees | Export-Csv -Path "C:\data\updated_employees.csv" -NoTypeInformation
Параметр -NoTypeInformation
предотвращает добавление строки с метаданными в начало файла, которая в большинстве случаев не нужна.
Некоторые нюансы
PowerShell по умолчанию использует кодировку UTF-16 для CSV. Если требуется другая кодировка (например, UTF-8 для совместимости), можно указать её явно:
$employees | Export-Csv -Path "C:\data\employees_utf8.csv" -NoTypeInformation -Encoding UTF8
Для работы с огромными CSV-файлами стоит избегать загрузки всего файла в память, используя построчную обработку. Это можно реализовать через потоковые методы вроде Get-Content
в комбинации с ConvertFrom-Csv
.
В заключение рекомендую к посещению открытые уроки по администрированию Windows: