Структурована обробка даних у PowerShell – це ключова навичка для професіоналів у галузі ІТ та кібербезпеки. PowerShell, потужний інструмент Microsoft для автоматизації задач та скриптингу, дозволяє ефективно маніпулювати та обробляти дані. У цій статті ми досліджуємо, як використовувати PowerShell для структурованої обробки даних, включаючи читання, аналіз, трансформацію та збереження даних. Ми розглядаємо ключові команди та техніки, які допоможуть вам працювати з різними форматами даних, включаючи текст, CSV, JSON та інші. Цей навик надзвичайно корисний для ефективного управління даними та автоматизації складних завдань.
В інформаційних системах повсюдно використовуються дані з певною структурою (конфігураційні файли, журнали транзакцій, дані з APls зовнішніх систем і т.д.). PowerShell має вбудовані інструменти для роботи з найпоширенішими форматами цих даних. У цій статті ви знайдете інформацію про структуровану обробку даних за допомогою PowerShell. Ми детально розглядаємо різні методи та команди PowerShell для роботи з даними, включаючи читання, аналіз, трансформацію та збереження в різних форматах. Ця стаття надасть вам практичні знання та навички, які можна використовувати для підвищення ефективності обробки даних у вашій повсякденній роботі.
У найпростішому випадку структурований файл містить табличні дані і являє собою набір рядків, що складаються з окремих полів, відокремлених один від одного певним символом. Часто в якості роздільника вибирають кому, тому такі файли і називаються (Значення, розділені комами, розділені комами).
У першому рядку CSV-файла можуть бути перераховані назви полів, а в інших містяться самі дані. Наприклад:
Name, Lastname, Age Иван,Петров,22 Сергей,Андреев,34 Оль га,Белова,2 5 Мария,Никитина,41
Розглянемо, як за допомогою PowerShell можна читати та змінювати дані в CSV-файлах.
Для розгляду прикладів створимо в каталозі C:\Script файл test.csv з такими анкетними даними (ім’я, прізвище та вік):
Name, Lastname, Age Иван,Петров,22 Сергей,Андреев,34 Оль га,Белова,2 5 Мария,Никитина,41
В принципі, вміст, як і будь-який інший текстовий файл, можна прочитати в масив рядків за допомогою командлета Get-Content.
PS C:\Script> $names = Get-Content .\test.csv PS C:\Script> Get-Member -Inputobject $names TypeName: System.Object[] PS C:\Script> $names | Get-Member TypeName: System.String . z. . PS C:\Script> $names Name,Lastname,Age Иван,Петров,22 Сергей,Андреев, 34 Оль га,Белова,2 5 Мария,Никитина, 41
Однак командлет Get-Content нічого не знає про внутрішню структуру рядків, тому вам доведеться проаналізувати вміст, щоб витягти його складові частини з рядків.
Тому для розбору структурованих даних з нього краще використовувати спеціальний командлет Import-Csv, який відразу перетворює дані з файлу в масив об’єктів з потрібними полями.
За допомогою Import-Csv зчитуємо дані з файлу test.csv в змінну $names і виводимо її вміст:
PS C:\Script> $names = Import-Csv -Path .\test.csv PS C:\Script> $names Name Lastname Age Иван Петров 22 Сергей Андреев 34 Ольга Белова 25 Мария Никитина 41
Як бачите, командлет Import-Csv зрозумів, що перший рядок файлу містить заголовок, який визначає структуру кожного рядка. Як і у випадку з Get-Content, змінна $names є масивом об’єктів:
PS C:\Script> Get-Member -Inputobject $names TypeName: System.Object[] Name MemberType Definition Count AliasProperty Count = Length Add Address Method Method int IList.Add(System... System.Objects, msco...
Однак тепер кожен елемент масиву $names є не простим рядком, а об’єктом типу PSCustomObject, який має поля Name, LastName та Ade:
PS C:\Script> $nanes | Get-Member TypeName: System.Management.Automation.PSCustomObject Name MemberType Definition Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() Age NoteProperty string Age=22 Lastname NoteProperty string Lastname=neTpoB Name NoteProperty string Name=HBaH
За допомогою цього масиву ми можемо легко шукати, сортувати або групувати дані за допомогою командлетів, розглянутих у главі 5. Для прикладу відсортуємо записи з нашої таблиці за віком:
PS C:\Script> $names | Sort-Object Age Name Lastname Age Иван Петров 22 Ольга Белова 25 Сергей Андреев 34 Мария Никитина 41
Назви полів при імпорті можна змінити за допомогою -Header:
PS C:\Script> Import-Csv -Path .\test.csv -Header 'Имя', 'Фамилия', 'Возраст' Имя Фамилия Возраст Name Lastname Age Иван Петров 22 Сергей Андреев 34 Ольга Белова 25 Мария Никитина 41
За замовчуванням import-csv вважає розділником кому. Якщо у файлі як розділювача використовується інший символ, його потрібно вказати в параметрі -Delimiter. Наприклад, замінимо у файлі test.csv коми на символ крапки з комою:
PS C:\Script> (Get-Content .\test.csv -Raw).Replace(',', ';') | Set-Content
.\test.csv
PS C:\Script> Get-Content .\test.csv
Name;Lastname;Age
Иван;Петров;22
Сергей;Андреев;3 4
Оль га;Белова;2 5
Мария;Никитина;41
Імпортувати такий файл можна наступною командою:
PS C:\Script> Import-Csv -Path .\test.csv -Delimiter
Name Lastname Age
Иван Петров 22
Сергей Андреев 34
Ольга Белова 25
Мария Никитина 41
За допомогою командлета Export-Csv можна сформувати CSV-файл із масиву об’єктів PowerShell. Наприклад, отримаємо список усіх запущених на локальному комп’ютері служб (статус, ім’я та ім’я, що відображається):
Збережемо цей список у змінній $services:
PS C:\Script> $services = Get-Service | Where-Object Status -eq Running | Select-Object Status, Name, DisplayName Експортуємо масив об'єктів $services до CSV-файлу services.csv: PS C:\Script> $services | Export-Csv -Path .\services.csv
Перевіримо вміст файлу services.csv:
PS C:\Script> Get-Content .\services.csv #TYPE Selected.System.ServiceProcess.Servicecontroller "Status","Name","DisplayName" "Running","AdobeARMservice","Adobe Acrobat Update Service" "Running","AMD External Events Utility","AMD External Events Utility" "Running","AMD FUEL Service","AMD FUEL Service"
Як бачите, файл був створений коректно, але в його першому рядку міститься тип об’єктів, з яких він був отриманий (в нашому випадку це об’єкти типу Se1ected). Система. ServiceProcess . ServiceContr011er). Якщо вам не потрібна ця інформація у файлі, вам слід вказати параметр -NoTypeInformation під час виклику Export-Csv:
PS C:\Script> $services | Export-Csv -Path .\services.csv -NoTypeinformation
У цьому випадку перший рядок у файлі міститиме назви полів:
PS C:\Script> Get-Content .\services.csv "Status","Name","DisplayName" "Running","AdobeARMservice","Adobe Acrobat Update Service" "Running","AMD External Events Utility","AMD External Events Utility" "Running","AMD FUEL Service","AMD FUEL Service" "Running","Appinfo","Application Information"
PowerShell має командлети ConvertFrom-Csv і ConvertTo-Csv, які працюють подібно до ImportFrom-Csv та ExportTo-Csv, але не мають доступу до зовнішніх файлів.
Для прикладу повторимо наш приклад зі списком запущених сервісів:
PS C:\Script> $services = Get-Service | Where-Object Status -eq Running | Select-Object Status, Name, DisplayName
Перетворюємо масив об’єктів $services на CSV:
PS C:\Script> $csv = $services | ConvertTo-Csv
У змінній $csv міститься рядок у CSV-форматі:
PS C:\Script> $csv | Get-Member TypeName: System. String PS C:\Script> $csv #TYPE Selected.System.ServiceProcess.Servicecontroller "Status", "Name","DisplayName" "Running","AdobeARMservice","Adobe Acrobat Update Service" "Running","AMD External Events Utility","AMD External Events Utility" "Running","AMD FUEL Service","AMD FUEL Service"
Тепер конвертуємо рядок $csv у змінну $objs:
PS C:\Script> $objs = $csv | ConvertFrom-Csv
Масив Sobjs міститиме об’єкти типу Selected. System. Serviceprocess. Servicecontroller, який був вказаний у коментарі #type:
PS C:\Script> Get-Mamber -Inputobject $objs TypeName: System.Object[] PS C:\Script> $objs | Get-Member TypeName: CSV:Selected.System.ServiceProcess.Servicecontroller PS C:\Script> $objs Status Name DisplayName Running AdobeARMservice Adobe Acrobat Update Service Running AMD External Events Utility AMD External EventsUtility Running AMD FUEL Service AMD FUEL Service
Дані у форматі JSON (JavaScript Object Notation) широко використовуються у веб-розробці, а також для зберігання налаштувань додатків. У PowerShell працювати з JSON МОЖНА З ДОПОМОГЮ командлетів ConvertFrom- Json І ConvertTo-Json. Примітка На відміну від CSV, спеціальних командлетів для імпорту/експорту JSON-файлів у PowerShell немає.
Давайте перетворимо на JSON вміст нашого CSV-файлу C:\Script\test.csv. Для цього ми спочатку імпортуємо цей файл у масив об’єктів PowerShell, а потім конвертуємо цей масив у JSON, передавши його конвеєром командлету convertToJson:
PS C:\Script> Import-Csv -Path .\test.csv
Name Lastname Age
Иван Петров 22
Сергей Андреев 34
Ольга Белова 25
Мария Никитина 41
PS C:\Script> Import-Csv -Path .\test.csv | ConvertTo-Json
[
{
"Name": "Иван",
"Lastname": "Петров",
"Age": "22"
},
"Name": "Сергей",
"Lastname": "Андреев",
"Age": "34"
{
"Name": "Ольга",
"Lastname": "Белова",
"Age": "25"
},
(
"Name": "Мария",
"Lastname": "Никитина",
"Age": "41"
}
]
Переконаємося, що в результаті виходить рядок:
PS C:\Script> $json = Import-Csv -Path .\test.csv | ConvertTo-Json PS C:\Script> Get-Member -Inputobject $json TypeName: System.String
За замовчуванням JSON-cTpoka генерується в структурованій формі, зручній для розуміння людиною: вкладені елементи мають відступи, поля розділені розривами рядків. Якщо JSON обробляється автоматично, ви можете використовувати опцію -Compress, щоб усунути непотрібні пробіли та розриви рядків для форматування. У цьому випадку поля і значення записуються послідовно, а JSON-cTpoka буде мати мінімальну довжину:
PS C:\Script> Import-Csv -Path .\test.csv | ConvertTo-Json -Compress
[{"Name":"Иван","Lastname":"Петров","Age":"22"},{"Name":"Сергей","Lastname":
"Андреев","Age":"34"},{"Name":"Ольга","Lastname":"Белова","Age":"25"},{"Name":"
Мария","Lastname":"Никитина","Age":"41"}]
Для створення файлу у форматі JSON отриманий в результаті конвертації рядок потрібно зберегти за допомогою командлетів set-content або Out-File:
PS C:\Script> Inport-Csv -Path .\test.csv | ConvertTo-Json | Set-Content .\test.json
Зазначимо, що на відміну від експорту в CSV-файл, при конвертації масиву об’єктів у JSON інформація про початковий тип об’єктів втрачається. Для ілюстрації цього знову створимо масив $services, в якому зберігатиметься список запущених на локальному комп’ютері служб:
PS C:\Script> $services = Get-Service | Where-Object Status -eq Running | Select-Object Status, Name, DisplayName Елементами цього масиву будуть об'єкти типу Selected.System.Serviceprocess. Servicecontroller: PS C:\Script> $services | Get-Member TypeName: Selected.System.ServiceProcess.Servicecontroller Перетворимо масив $services в JSON и сохраним результат в переменной $json_ services: PS C:\Script> $json_services = $services | ConvertTo-Json
Тепер виконаємо зворотне перетворення – конвертуємо рядок $json_services у масив $objs З ДОПОМОГЮ командлета ConvertFrom-Json:
PS C:\Script> $objs = $json_services | ConvertFrom-Json
Перевіримо, який тип мають елементи масиву $objs:
PS С:\Users\andrv> $objs | Get-Member TypeName: System.Management.Automation.PSCustomObject Name MemberType Definition Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() DisplayName NoteProperty string DisplayName=Adobe Acrob Name NoteProperty string Name=AdobeARMservice Status NoteProperty int Status=4
Як бачимо, в результаті перетворення з JSON-рядка $json_services створюються об’єкти типу System.Management.Automation.PSCustomObject. Ці об’єкти мають ті ж поля, що були у початкових об’єктів типу Selected. System. Serviceprocess.servicecontroller, проте специфічні методи для керування службами в перетворених з JSON об’єктах будуть недоступні.
Для роботи з найбільш поширеними форматами структурованих даних PowerShell використовуються командлети ConvertFrom-*, ConvertTo-*.
Читати та змінювати CSV-файли можна за допомогою командлетів import-csv та export-csv.