Как создать объект, который выводит список (не таблица)

Это отключение от другого вопроса, который находится здесь: Форматирование объекта как аккуратно выглядящего списка . Основа аргумента, я считаю, была неправильной, поскольку мы не имеем дело с форматированием объекта впоследствии. Это только для окон, показанных консолью, но может иметь отношение к целостности объекта при манипулировании переменной, содержащей объект.

Мне нужно создать объект, который по сути выводит список (а не таблицу). Я знаю, что это возможно, потому что я проверил множество функций, которые я не написал, и созданные объекты фактически являются списками. Нет необходимости использовать Format-List для искажения или формирования того, что уже существует. Я просто не могу понять, почему иногда вывод представляет собой список или таблицу. Я не уверен, где волшебство. Однако я знаю, что когда я запускаю $Host прежде чем запускать переменную, содержащую созданный объект, я получаю объект, который производит узел, который представляет собой список, и который затем формирует объект также как список, который обычно будет отображаться в виде таблицы. Конечно, это может дать результат, который я хочу, но я не хочу показывать информацию о хосте. Итак, каково решение этого, я хочу, чтобы кто-то мог это объяснить.

PowerShell делает некоторое форматирование по умолчанию, когда он представляет данные / объекты пользователю. Обычно объекты отображаются в табличной форме, когда у них есть до 4 свойств, и в форме списка, когда они имеют более 4 свойств.

Если вы выводите несколько строк подряд, PowerShell применяет формат (список / таблицу) от первого объекта ко всем последующим объектам. Я не знаю точной причины этого поведения, но, по-видимому, это должно сделать вывод более последовательным.

Демонстрация:

 PS C: \> $ o1 = New-Object -Type PSObject -Property @ {a = 1; b = 2; c = 3; d = 4; e = 5}
 PS C: \> $ o2 = New-Object -Type PSObject -Property @ {x = 'foo'; y = 'bar'}
 PS C: \> $ o1

 c: 3
 e: 5
 d: 4
 Би 2
 a: 1

 PS C: \> $ o2

 уг
 - -
 бар foo

 PS C: \> $ o1;  $ o2

 c: 3
 e: 5
 d: 4
 Би 2
 a: 1

 y: bar
 x: foo

Помните, однако, что использование этого поведения может привести к нежелательным результатам, если вы выведете объекты в неправильном порядке:

 PS C: \> $ o2;  $ o1

 уг
 - -
 bar foo # ← свойства $ o2 
                                                   # ← пустая строка для $ o1!

$o1 появляется как пустая строка в вышеприведенном выходе, потому что вывод $o2 сначала устанавливает табличный формат вывода с столбцами y и x , но $o1 не имеет этих свойств. Отсутствующие свойства отображаются в виде пустых значений в табличном выводе, тогда как дополнительные свойства исключаются из вывода. Также есть случаи, когда вы можете получить результат из второго объекта / списка в виде списка (например, запустить Get-Process; Get-ChildItem в консоли PowerShell).

Вы можете принудительно отображать последующие объекты или массивы объектов в виде отдельных таблиц (или списков), связывая их с помощью командлета Format-Table (или Format-List ):

 PS C: \> $ o2;  $ o1 |  Format-Table

 уг
 - -
 бар foo


               cedba
               - - - - -
               3 5 4 2 1

Вы также можете заставить PowerShell отображать каждую переменную по отдельности, используя их (например) Out-Default :

 PS C: \> $ o2 |  Из-умолчанию;  $ o1 |  Из-умолчанию

 уг
 - -
 бар foo

 c: 3
 e: 5
 d: 4
 Би 2
 a: 1

Обратите внимание, однако, что это записывается на консоль, поэтому итоговый результат не может быть захвачен, перенаправлен или конвейер. Используйте это, только если вы хотите отобразить что-то пользователю.

Дополнительную информацию о форматировании вывода PowerShell см. Здесь .


Есть способы изменить поведение по умолчанию, как объект отображается, но, к сожалению, они не совсем понятны. С одной стороны, вы можете определить свойство отображения по умолчанию, установленное для отображения PowerShell не всех свойств, а только определенного подмножества.

 PS C: \> $ props = 'c', 'd'
 PS C: \> $ default = New-Object Management.Automation.PSPropertySet ('DefaultDisplayPropertySet', [string []] $ props)
 PS C: \> $ members = [Management.Automation.PSMemberInfo []] @ ($ default)
 PS C: \> $ o1 |  Участник-член MemberSet PSStandardMembers $ members
 PS C: \> $ o1

                 CD
                 - -
                 3 4

Вы все равно можете отобразить все свойства с помощью Format-List * :

 PS C: \> $ o1 |  Формат-список *

 c: 3
 e: 5
 d: 4
 Би 2
 a: 1

Определение заданного свойства отображения по умолчанию не позволяет вам определять формат вывода. Для этого вам, вероятно, нужно написать собственный файл форматирования . Для этого вам, вероятно, также необходимо определить настраиваемый тип для ваших объектов.

 $formatFile = "$HOME\Documents\WindowsPowerShell\Your.Format.ps1xml" $typeFile = "$HOME\Documents\WindowsPowerShell\Your.Type.ps1xml" @'     Default  Foo.Bar   ...     '@ | Set-Content $formatFile Update-FormatData -AppendPath $formatFile @'    Foo.Bar  ...    '@ | Set-Content $typeFile Update-TypeData -AppendPath $typeFile $o2.PSTypeNames.Insert(0, 'Foo.Bar') По $formatFile = "$HOME\Documents\WindowsPowerShell\Your.Format.ps1xml" $typeFile = "$HOME\Documents\WindowsPowerShell\Your.Type.ps1xml" @'     Default  Foo.Bar   ...     '@ | Set-Content $formatFile Update-FormatData -AppendPath $formatFile @'    Foo.Bar  ...    '@ | Set-Content $typeFile Update-TypeData -AppendPath $typeFile $o2.PSTypeNames.Insert(0, 'Foo.Bar') 

Джеффри Хикс написал серию статей по этой теме, которую вы можете прочитать.


Со всем сказанным я бы не рекомендовал идти по этому маршруту, если у вас нет очень веских причин для этого. Я пытался объяснить это раньше, но @TesselatingHeckler произнес это гораздо более кратко, чем я, поэтому я собираюсь процитировать его по этому поводу :

PowerShell не bash, он разделяет контент и презентацию, как HTML и CSS.

То, что вы обычно хотите делать в PowerShell, – это хранить ваши данные в объектах и ​​иметь свойства этих объектов, содержащие «необработанные» (т.е. неформатированные) данные. Это дает вам максимальную гибкость при обработке ваших данных. Форматированные данные обычно только мешают, потому что это заставляет вас снова анализировать / преобразовывать данные. Отформатируйте свои данные только тогда, когда вам нужно отобразить их для пользователя, и для этого используйте командлеты Format-* . И если ваш выход предназначен для дальнейшей обработки: не надо форматировать его в первую очередь. Оставьте его пользователю, как он хочет отображать данные.

  • Разница между скобками и двойной скобкой ] для доступа к элементам списка или кадра данных
  • Сгладить список в LINQ
  • ссылка на устаревший элемент: элемент не привязан к документу страницы
  • List.Except не работает
  • В чем разница между неограниченным подстановочным типом List И сырым списком типов?
  • Как удалить строки между ListViews на Android?
  • Почему нет оператора для std :: list?
  • Почему массивы инвариантны, но списки ковариантны?
  • Как удалить элемент из списка python в цикле?
  • Есть ли что-то вроде общего списка в Cocoa / Objective-C?
  • Использование LINQ для удаления элементов из списка
  • Давайте будем гением компьютера.