Давайте работать через это. Когда мы указываем -o table
, например:
az group list -o table
Мы говорим Azure PowerShell CLI взять полученный JSON-контент и отформатировать его в удобную для нас таблицу. Как правило, мы не хотим работать с RAW JSON и не хотим работать с отформатированными таблицами. Работа со строковыми массивами в PowerShell также не очень удобна. В PowerShell мы хотим работать с «красивыми» легкими объектами. Итак, давайте посмотрим на другие способы получения нашей информации. Давайте возьмем ваш пример и просто сохраним его в переменной, на которую мы можем посмотреть:
$GroupList = az group list
Тогда, если мы посмотрим на тип:
PS C:\> $GroupList.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
Действительно, у нас есть массивобъекты. Они должны быть массивом наших групп ... верно? ... ну нет. Это не то, что вы думаете. Если мы посмотрим на размер массива и вернем первые несколько элементов массива, мы увидим, что происходит:
PS C:\> $GroupList.Count
125
PS C:\Temp> $GroupList[0..2]
[
{
"id": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/somegroup",
Ну, это не то, что мы хотели. Массив слишком велик ... и просмотр содержимого показывает, что на самом деле мы имеем массив каждой строки текста JSON . Это означает, что выполнение:
az group list | select -p name
или:
$GroupList | select -p name
Говорит, перебирает массив и выводит только свойство «Имя». Поскольку свойство «Имя» не существует в текстовой строке, оно просто выводит пустую строку. Поскольку в тексте несколько сотен строк, мы получаем несколько сотен строк пробелов.
Так почему PowerShell принимает входные данные и разбивает их на массив строк, разделенных новыми строками? Разве это не сложно использовать? Разве это не "отличный" способ обработки текста в формате JSON? Почему бы нам просто не получить одну гигантскую нить? Разве это не легче обрабатывать и анализировать? В чем причина такой странности?
Что касается PowerShell, то необходимость поддержки конвейеров приводит к принятию решений о том, как мы выводим объекты:
«Основная цель ... способ гарантировать, что результатом выполнения конвейера всегда будет индексируемая коллекция. " Цитата
Вот почему мы получаем выводимый массив объектов (см. Ответ @ mklement0 здесь для более подробного обсуждения ) для поддержки операций конвейера. И если мы посмотрим, как текстовые файлы читаются и записываются, мы можем точно указать, почему мы получаем именно этот кашель Программист кашель удобство кашель ... я имею в виду странность.
Чтобы все настроить, мы можем направить вывод напрямую в текстовый файл:
az group list | Out-File -FilePath List.json
Ух, подожди секунду, почемуэто просто работа? (В подобных ситуациях я хотел бы сказать, что PowerShell выполняет Magic! ). Не нужно ли нам возиться с циклическим перебором массивов, добавляя строки, заканчивающиеся символами новой строки, чтобы получить один гигантский непрерывный блок текста, который заканчиваетсяс EOF, и точно соответствует нашему желаемому текстовому файлу?
Упрощенная причина того, что на самом деле происходит? Ну, из-за удобства программиста, Out-File
берет массив строк, перебирает его и делает простое File.WriteLine()
для каждой строки (неплохо для 3 строки для цикла!). Следовательно, мы только что сгенерировали хороший форматированный текстовый файл JSON с символами новой строки, без проблем. Читая это обратно:
PS C:\> $ListFromFile = Get-Content .\List.json
PS C:\> $ListFromFile.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS C:\> $ListFromFile.Count
125
Делает обратное. Он берет файл, делает File.ReadLine()
, добавляет строки в массив и возвращает его. Вот почему мы получаем массив объектов, содержащий строки.
Теперь, что мы действительно хотим? Ну, мы знаем с самого начала, мы не хотим работать с одной гигантской строкой, и мы особенно не хотим работать со строками в массиве объектов, что мы хотимработать с это хороший нативный PSCustomObject
, к которому мы можем получить доступ. Это то, с чем лучше всего работает PowerShell, это то, с чем мы лучше всего работаем. Таким образом, мы просто должны преобразовать наши (большие воздушные кавычки) «ввод текста», который, как мы знаем, отформатирован как JSON, и преобразовать его в объект:
$List = $GroupList | ConvertFrom-Json
И с учетом количества и свойств:
PS C:\> $List.Count
10
PS C:\> $List.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS C:\> $List[0].GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
Мы видим, что счетчик теперь соответствует количеству групп, и типы больше не являются массивом строк, а являются действительными объектами. Итак ... Теперь , мы можем начать сортировку и выбрать:
PS C:\> $List | select -Property Name
Name
----
group0
group1
group2
group3
group4
group5
group6
group7
group8
group9
И мы получим вывод, который мы действительно хотели.