Привет, Хабр!

Сегодня рассмотрим, как в 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:

Комментарии (1)


  1. lioncub
    07.10.2024 15:26

    Раз такая пьянка, указали бы версию PS, т.к. с json будет много сюрпризов. Да и YML можно было добавить для полноты.