Пакетное переименование файлов и папок в Windows Powershell
У меня есть сотни тысяч файлов, расположенных в ~40 папках (эти подпапки находятся в одной и той же суперпапке, которую я назову "test"). Я попытался использовать powershell для замены синтаксиса, найденного в имени папки, но также и в именах файлов.
В основном мои папки и файлы содержат ту же строку символов "PXXXX_0", которую я хочу переименовать в "PXXXX_".
Вот код, который я использовал, чтобы сначала сопоставить интересующие файлы и папки
cd C:\test
Get-ChildItem -Filter "*PXXXX_0*" -Recurse | Rename-Item -NewName {$_.name -replace 'PXXXX_0', 'PXXXX_'} -whatif
Это дает мне нужные файлы и предварительное действие (например,
What if: Performing operation "Rename File" on Target "Item: C:\test\PXXXX_053\PXXXX_053_558.jpg Destination C:\test\PXXXX_053\PXXXX_53_558.jpg
Так что, похоже, это работает, но только для файлов внутри папок, которые я также хочу переименовать.
Теперь, если я запускаю код без -whatif, оказывается, что переименовываются только имена папок, а не файлы...
Я почти уверен, что что-то пропустил, но так как я не очень знаком с этим языком, я изо всех сил пытаюсь найти решение. Я использую Powershell v1.0
Спасибо за любую помощь.
Лучший
1 ответ
Один лайнер:
$items = get-childitem -filter "*PXXXX_0*" -Recurse; foreach ($item in $items) { $newName = $item.fullname -replace 'PXXXX_0', 'PXXXX_'; rename-item $item.fullname -NewName $newName; }
Легко на глазных яблоках:
$items = get-childitem -filter "*PXXXX_0*" -Recurse;
foreach ($item in $items) {
$newName = $item.fullname -replace 'PXXXX_0', 'PXXXX_';
rename-item $item.fullname -NewName $newName;
}
Короче говоря, PowerShell 1 пытался переименовать файл, указав только имя файла, а не полный путь. По сути, он не смог найти ваши файлы, когда они были в подпапках.
Я проверил вашу логику в v5, и она работает так, как вы ожидаете.
Я собираюсь остановиться здесь и предположить, что вы пытаетесь запустить этот скрипт через System Center Orchestrator, так как вы работаете с PowerShell v1. Я чувствовал эту боль. Я рекомендую обернуть все ваши PS-скрипты в Runbooks в invoke-command -scriptblock {} -Credential $myCreds
блоки. Это способствует выполнению в версии PowerShell целевой системы. Это также упрощает использование -ComputerName для запуска сценария на целевом сервере вместо сервера Runbook.
Затем вы можете сохранить пару имени пользователя и пароля в качестве переменных Orchestrator (используйте опцию шифрования) и вставить их в свое заявление get-credential выше. Сначала это кажется очень грязным, но вы привыкли к этому.
чтобы проверить это, я запустил PowerShell с -version 1. Вот мой $PSVersionTable:
Name Value
---- -----
CLRVersion 2.0.50727.8689
BuildVersion 6.1.7600.16385
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
У него была та же проблема, но это не могло быть совпадением 1 к 1 с тем, что собирается запустить Orchestrator. Выведите вывод, если он не работает, и я сделаю все возможное.