я нашел сценарий PowerShell что я думал, что смогу приспособиться к своим целям.
Он содержит эту строку, которая форматирует вывод:
$largeSizefiles = get-ChildItem -path $filesLocation -include $Extension -recurse -ErrorAction "SilentlyContinue" | ? { $_.GetType().Name -eq "FileInfo" } | where-Object {$_.Length -gt $fileSize} | sort-Object -property length | Select-Object Name, @{Name="Size In KB";Expression={ "{0:N0}" -f ($_.Length / 1KB)}},@{Name="LastWriteTime";Expression={$_.LastWriteTime}},@{Name="Path";Expression={$_.directory}} -first $filesLimit
Ключевая часть, похоже, такова:
Select-Object Name, @{Name="Size In KB";Expression={ "{0:N0}" -f ($_.Length / 1KB)}},@{Name="LastWriteTime";Expression={$_.LastWriteTime}},@{Name="Path";Expression={$_.directory}} -first $filesLimit
Я прочитал учебник ss64.com по Select-Object, но не нашел ничего, что могло бы объяснить, как выражения формы @ {.....} форматируют текст.
В ss64.com страница с оператором @ показывает его в формате @ (...), в скобках, а не в фигурных скобках.
Приведенный выше код дает следующий результат:
Name : RPI-Image-1-Copy.img
Size In MB : 29,477
Path : D:\VirtualDriveShare
LastWriteTime : 8/18/2015 6:27:51 PM
Я знаком с рядом языков программирования, но для меня это неочевидно, и я не нашел четкого объяснения в Интернете. Может ли кто-нибудь указать мне на хороший учебник?
Select-Object может использовать хэш-таблицу заголовков / значений для каждого элемента. В этом примере:
Select-Object Name, @{Name="Size In KB";Expression={ "{0:N0}" -f ($_.Length / 1KB)}} ...
сценарий выбирает «Имя», затем «Имя в КБ», полученное на основе параметра Length текущего объекта конвейера.
Далее он форматируется, сначала делится на 1024, а затем используется {0: N0} для его отображения.
Powershell использует для отображения синтаксис строкового формата .Net - в этом случае {0: N0} переводится в:
// N or n (Number): It represent how many decimal places of zeros to show.
String.Format("{0:N4}", pos); //”10.0000″
Возможно, вы захотите взглянуть на статьи Кэти Кам в форматах 101 и 102:
https://blogs.msdn.microsoft.com/kathykam/2006/03/29/net-format-string-101/
https://blogs.msdn.microsoft.com/kathykam/2006/09/29/net-format-string-102-datetime-format-string/
для получения дополнительных сведений о форматировании строк.
Я согласен со всеми другими ответами, в этом случае хеш-таблица является вычисляемым свойством. Я считаю эти лайнеры замечательными, но они могли бы быть представлены гораздо лучше. Технический по-прежнему однострочный, но читаемость в другом масштабе.
$largeSizefiles = get-ChildItem `
-path $filesLocation `
-include $Extension `
-recurse `
-ErrorAction "SilentlyContinue" |
Where-object { ($_.GetType().Name -eq "FileInfo") `
-and ($_.Length -gt $fileSize)} |
sort-Object -property length |
Select-Object Name,
@{Name="Size In KB";Expression={ "{0:N0}" -f ($_.Length / 1KB)}},
@{Name="LastWriteTime";Expression={$_.LastWriteTime}},
@{Name="Path";Expression={$_.directory}} -first $filesLimit
Если PoSh ожидает продолжения (после ,
или |
) вы можете просто вставить новую строку или, конечно же, после символа продолжения строки символ `.
Вам не хватает того, что @{...}
указывает на массив хэш-таблиц, состоящий из пар ключ-значение.
Как указано в комментариях, есть Статья Technet именно по этому поводу. В вашем примере происходит то, что имя / заголовок назначается ключу в хэш-таблице, а переменная с выражением форматирования назначается значению в хеш-таблице.
Хеш-таблицы в PowerShell довольно просты, но если это полезно, Страница ss64 находится здесь, и У Technet есть обучающая страница также.
@{...=...; ...=...}
это хеш-таблица. Возможно, вы знаете их как «словари» на других языках. Это пары ключ / значение. Точка с запятой (;
) разделяют разные пары, а ключ и значение разделяются знаком равенства (=
). Обратите внимание, что ключ может иметь подразумеваемые кавычки, что делает его строкой.
В { "{0:N0}" -f ($_.Length / 1KB) }
часть - это блок скрипта. Их много; все Expression
ключи в хэш-таблицах соответствуют одному. Об этом можно судить по фигурным скобкам без префикса. По сути, это анонимные функции (лямбды). В $_
- это текущий элемент из конвейера, поэтому, когда этот блок скрипта выполняется, он расширяется до одного элемента из ввода конвейера.
Конкретный блок скрипта "{0:N0}" -f ($_.Length / 1KB)
часть просто использует -f
оператор делать форматирование. Это эквивалентно .NET String.Format
, где строка шаблона находится слева, а аргументы шаблона - это массив объектов справа. В 0
это просто индекс аргумента (т.е. первый аргумент), а :N0
сообщает ему форматирование как число с 0 десятичными знаками.
Теперь между всеми хэш-таблицами у нас есть связка запятых. Это делает массив! Получается, что окружающие @(...)
часть не является обязательной.
Итак, у нас есть массив, содержащий несколько строк и кучу хэш-таблиц с ключами Name
и Expression
, и этот массив является аргументом, передаваемым в Select-Object
. А именно это -Property
аргумент. Обратите внимание на эту строку из документа SS64:
Чтобы добавить вычисляемое свойство к объекту, укажите хеш-таблицу в качестве значения
-Property
параметр. Хеш-таблица должна включать два ключа: название и Выражение с ключом Expression, которому назначен блок сценария, который будет определять значение свойства.
Так что теперь все это имеет немного больше смысла. Это просто Select-Object
преобразование входных данных и объединение группы «вычисленных» (определяемых блоком сценария) атрибутов и одного «невычисленного» (уже присутствующего во входящем объекте) атрибута для выходного объекта.
Небольшое замечание: я считаю, что этот конкретный вычисляемый атрибут несколько глуп:
@{Name="LastWriteTime";Expression={$_.LastWriteTime}}
Я не вижу причин, по которым его нельзя было просто выбрать напрямую, например Name
был.