Как выбрать определенные значения хеш-таблицы, но изменить другие встроенные в сценарии powershell
Используя конвейеры или другие виды встроенных обозначений, я бы хотел "выбрать" определенные значения в хэш-таблице непосредственно до результата, изменяя или устанавливая другие.
Хеш-таблица
Я начинаю с хеш-таблицы (которая, откровенно говоря, используется как объект), например:
>$hash
Name Value
---- -----
System server-1
Job Microsoft.PowerShell.Commands.PSWmiJob
Result
Есть ли способ использовать командлет Select-Object (или что-нибудь подобное), чтобы установить значение определенных свойств и передать их другим? Я хотел бы закончить с этим:
>$hash
Name Value
---- -----
System server-1
Job Microsoft.PowerShell.Commands.PSWmiJob
Result Good
Если мне не нужно / нужно, чтобы оно было встроенным, я просто устанавливаю значение Result
:
$hash.Result = "good"
Для встроенного решения я всегда мог использовать Foreach-Object
как это:
$hash | Foreach-Object {@{System=$_.System;Job=$_.Job;Result="Good"}}
или просто обратитесь к $ hash в подвыражении:
${@{System=$hash.System;Job=$hash.Job;Result="Good"}}
Тем не менее, кажется бессмысленным использовать Foreach-Object
когда я обрабатываю только одну хеш-таблицу, и довольно многословно упоминать свойства дважды, которые я просто хочу передать в любом случае, и тогда это может быть громоздким, если мой $hash
переменная $aSignificantlyLongerHashTableVariableName
,
Если бы я использовал объект Powershell...
Если бы я использовал такой объект:
>$obj
System Job Result
------ --- ---
server-1 Microsoft.PowerShell.Commands.PSWmiJob
Я бы использовал select-object
Командлет, как это:
>$obj | Select-Object System, Job, @{Name="Result";Expression="Good"}
что приведет к
>$obj
System Job Result
------ --- ---
server-1 Microsoft.PowerShell.Commands.PSWmiJob Good
У Hashtable и PSObject есть некоторые сходные аспекты (то, что содержит другие вещи в названном виде), но AFAIK, они несовместимы - есть ли альтернатива, более близкая к Select-Object
что я пытаюсь сделать здесь?
4 ответа
Будучи строгим в отношении того, чтобы это было как однострочный, у которого нет кода установки заранее и не изменяется хеш-код источника, что-то подобное может сделать эту работу:
($hash + @{ 'Result' = 'Good' }).GetEnumerator() | ? {$_.Key -in 'Result','System','Job'}
Если вы собираетесь что-то добавить Result = Good
регулярно может быть полезно сохранить ваши маленькие биты расширения:
$good = @{ 'Result' = 'Good' }
И тогда ваш однострочник становится:
($hash + $good).GetEnumerator() | ? {$_.Key -in 'Result','System','Job'}
Изменить: как вы отметили в комментариях ниже, что один вкладыш умрет, если Result
существует в хеше. Эта версия немного безопаснее / более явна и более точно соответствует духу того, что вы описали Select-Object
на PSObjects:
(($hash).GetEnumerator() | ? {$_.Key -in 'System','Job'}) + @{'Result' = 'Good'}
Все еще не самая красивая вещь в мире, но это делает работу.
Для анализа однозначного объекта используйте это:
$hash = @{}
$hash.Add("System",$obj.System)
$hash.Add("Job"=$obj.job)
$hash.Add("Result"="Good")
Если вам нужно больше объектов - итерируйте их foreach($o in $obj){$hash.Add()}
, но объявите хеш перед циклом.
Если вам просто нужно добавить или обновить ключ в вашей хеш-таблице:
$ hash.Result + = 'Хорошо'
Если ключ Result существует, его значение будет установлено на "Хорошо". Если он не существует, он будет добавлен с этим значением.
Когда вы используете Select-Object
и добавить столбец (свойство), который не существует, вы по существу создаете новый [PSObject]
это оборачивает оригинал. Вы можете сделать это явно и использовать [hashtable]
инициировать его свойства двумя способами:
$obj = [PSCustomObject]$hash
или же
$obj = New-Object PSObject -Property $hash
Оттуда вы можете использовать Select-Object
по-прежнему. Вы также можете сначала манипулировать хешем, чтобы получить нужные свойства, а затем преобразовать в объект и пропустить Select-Object
,