Рассмотрим следующий скрипт Powershell, который ищет папки в C: \ с именем 'og':
PS C: \> (ls |% {$ _. Name} |? {$ _. Contains ("og")}) Perflogs Файлы программ setup.log
Теперь я сужу поиск, чтобы получить только один элемент:
PS C: \> (ls |% {$ _. Name} |? {$ _. Contains ("Prog")}) Файлы программ
Странно то, что первая операция выдает массив , тогда как вторая операция (которая ИМХО является семантически той же самой операцией, поэтому она должна давать тот же тип результата) выдает строку . Это можно увидеть в следующем результате:
PS C: \> (ls |% {$ _. Name} |? {$ _. Contains ("og")}). Длина 3 PS C: \> (ls |% {$ _. Name} |? {$ _. Contains ("Prog")}). Длина 13
Это может быть очень раздражающим, так как очевидно, что меньше папок, которые соответствуют 'og', чем папок, которые соответствуют 'Prog'.
Очевидно, что PowerShell неявно «распаковывает» массив из одного элемента в один объект, и мы никогда не получаем массив длины 1. Кажется, что каждый раз, когда я хочу подсчитать результаты, поступающие по конвейеру, я должен проверить, не Я имею дело с массивом или нет.
Как я могу предотвратить это? Как вы справляетесь с этим?
источник
$_.Contains
, то%{,,$_.Name}
работает ...Ответы:
И нулевой результат приводит к
$null
.Ты не можешь
Используйте конструктор массива (
@(...)
) для принудительного возврата коллекции (возможно, с нулем или одним элементом):источник
@(1) | ConvertTo-Json
все еще возвращается1
вместо[1]
.ConvertTo-Json
никогда не возвращает коллекцию: он читает весь ввод и преобразует в одну строку. Если вы хотите, чтобы входные объекты конвертировались индивидуально, вам нужно обрабатывать каждый отдельно.Это было решено в PowerShell v3:
http://blogs.microsoft.co.il/blogs/scriptfanatic/archive/2012/03/19/Counting-objects-in-PowerShell-3.0.aspx
В примечании вы можете найти, содержит ли имя что-то, используя подстановочный знак:
источник
Обратите внимание на разницу между этими двумя результатами:
Дело в том, что «распаковка» выполняется конвейером. ConvertTo-Json по-прежнему видит объект как массив, если мы используем InputObject, а не трубопровод.
источник