Назад | Перейти на главную страницу

Как расшифровать синтаксис Powershell для форматирования текста?

я нашел сценарий 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:

для получения дополнительных сведений о форматировании строк.

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

$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 был.