Причина, по которой вы не можете просто использовать $count++
в своем блоке сценария для непосредственного увеличения порядкового номера:
Блоки сценариев с задержкой привязки - например, тот, который вы передали Rename-Item -NewName
- и блоки скриптов в вычисленные свойства , выполняемые в дочернем области .
- Сравните это с блоками сценариев, переданными в
Where-Object
и ForEach-Object
, которые выполняются непосредственно в области действия вызывающего.преднамеренное .
Следовательно, , пытаясь изменить переменные вызывающего, вместо этого создает block -локальную переменную, которая выходит из области видимости вкаждая итерация , поэтому следующая итерация снова увидит исходное значение из области видимости вызывающего.
- Чтобы узнать больше о областях и неявном создании локальной переменной, см. этот ответ .
Обходные пути
A прагматичный, но потенциально ограничивающий обходной путь заключается в использовании спецификатора области $script:
- т.е. $script:count
- для ссылки на переменную $count
вызывающего абонента:
$directory = 'C:\Temp'
[int] $count=71
gci $directory | sort -Property LastWriteTime |
rename-item -newname { '{0}_{1}' -f $script:count++, $_.Name } -whatif
Thisбудет работать:
в интерактивном сеансе (в командной строке, в глобальной области действия).
в сценарии, покапеременная $count
была инициализирована в области верхнего уровня сценария .
- То есть, если вы переместили свой код в функцию с помощью переменная локальная
$count
, больше не будет работать.
Гибкое решение требует надежного относительного ссылка на родительский охват :
Существует два варианта:
- концептуально ясный, но многословный и сравнительно медленный , из-за необходимости вызова командлета:
(Get-Variable -Scope 1 count).Value++
gci $directory | sort -Property LastWriteTime |
rename-item -newname { '{0}_{1}' -f (Get-Variable -Scope 1 count).Value++, $_.Name } -whatif
- несколько неясно, но быстрее и более кратко :
([ref] $count).Value++
gci $directory | sort -Property LastWriteTime |
rename-item -newname { '{0}_{1}' -f ([ref] $count).Value++, $_.Name } -whatif
[ref] $count
фактически совпадает с Get-Variable -Scope 1 count
(при условии, что в родительской области была установлена переменная $count
)
Примечание: Теоретически вы можете использовать $global:count
для инициализации и приращения глобальной переменной в любой области, но с учетом того, что глобальные переменные задерживаются даже после завершения выполнения скрипта, вам также следует предварительно сохранить любое существующее значение $global:count
заранееи восстановить его впоследствии, что делает этот подход нецелесообразным.