Переименовать файлы в нижний регистр в Powershell - PullRequest
19 голосов
/ 29 сентября 2010

Я пытаюсь рекурсивно переименовать группу файлов с помощью Powershell 2.0.Структура каталогов выглядит следующим образом:

Leaflets
+ HTML
  - File1
  - File2
  ...
+ HTMLICONS
  + IMAGES
    - Image1
    - Image2
  - File1
  - File2
  ...
+ RTF
  - File1
  - File2
  ...
+ SGML
  - File1
  - File2
  ...

Я использую следующую команду:

get-childitem Leaflets -recurse | rename -newname { $_.name.ToLower() }

и, похоже, переименовывает файлы, но жалуется на подкаталоги:

Rename-Item : Source and destination path must be different.

Я перезагружаю данные ежемесячно, используя robocopy, но каталоги не меняются, поэтому я могу переименовать их вручную.Есть ли способ заставить get-children пропустить подкаталоги (например, find Leaflets -type f ...)?

Спасибо.

ОБНОВЛЕНИЕ: Похоже, что проблема с файламиэто уже все строчные.Я попытался изменить команду на:

get-childitem Leaflets -recurse | if ($_.name -ne $_name.ToLower()) rename -newname { $_.name.ToLower() }

, но теперь Powershell жалуется, что if не является командлетом, функцией и т. Д. Можно ли направить вывод get-childitem в оператор if?

ОБНОВЛЕНИЕ 2 : Это работает:

$files=get-childitem Leaflets -recurse
foreach ($file in $files)
{
    if ($file.name -ne $file.name.ToLower())
    {
        rename -newname { $_.name.ToLower() }
    }
}

Ответы [ 6 ]

23 голосов
/ 29 сентября 2010

Даже если вы уже опубликовали свой собственный ответ, здесь есть вариант:

dir Leaflets -r | % { if ($_.Name -cne $_.Name.ToLower()) { ren $_.FullName $_.Name.ToLower() } }

Некоторые пункты:

  • dir - псевдоним для Get-ChildItem (и -r - сокращение от -Recurse).
  • % - псевдоним для ForEach-Object .
  • -cne - сравнение с учетом регистра. -ne игнорирует различия регистра.
  • $ _ - это способ ссылки на текущий элемент в цикле ForEach-Object.
  • ren является псевдонимом для Rename-Item .
  • FullName , вероятно, предпочтительнее, поскольку он гарантирует, что вы будете касаться нужного файла.

    Если вы хотите исключить переименование каталогов, вы можете добавить что-то вроде:

    if ((! $_.IsPsContainer) -and $_.Name -cne $_.Name.ToLower()) { ... }
    

    Надеюсь, это поможет вам продолжить изучение и изучение PowerShell.

12 голосов
/ 29 сентября 2010

Имейте в виду, что вы можете направить напрямую к Rename-Item и использовать Scriptblocks с параметром - NewName (поскольку он также принимает входные данные конвейера) для упрощения этой задачи:

Get-ChildItem -r | Where {!$_.PSIsContainer} | 
                   Rename-Item -NewName {$_.FullName.ToLower()}

и с псевдонимами:

gci -r | ?{!$_.PSIsContainer} | rni -New {$_.FullName.ToLower()}
2 голосов
/ 15 октября 2013

Небольшая настройка: если вы хотите обновить только имена файлов определенного типа, попробуйте следующее:

get-childitem *.jpg | foreach { if ($_.Name -cne $_.Name.ToLower()) { ren $_.FullName $_.Name.ToLower() } }

это только строчные буквы jpg файлов в вашей папке и игнорировать остальные

1 голос
/ 19 июня 2018

Существует много проблем с предыдущими ответами из-за особенностей работы Rename-Item, Piping, Looping и Windows Filesystem. К сожалению, самое простое (не использующее здесь псевдонимы для удобочитаемости) решение, которое я нашел для переименования всех файлов и папок внутри данной папки в нижний регистр, это:

Get-ChildItem -Path "/Path/To/You/Folder" -Recurse | Where{ $_.Name -cne $_.Name.ToLower() } | ForEach-Object { $tn="$($_.Name)-temp"; $tfn="$($_.FullName)-temp"; $nn=$_.Name.ToLower(); Rename-Item -Path $_.FullName -NewName $tn; Rename-Item -Path $tfn -NewName $nn -Force; Write-Host "New Name: $($nn)";}
1 голос
/ 07 сентября 2016

Вам нужно временно переименовать их во что-то другое, а затем переименовать их в нижний регистр.

$items = get-childitem -Directory -Recurse

foreach ($item in $items)
{

   if ($item.name -eq $item.name.ToLower())
   {    

       $temp = $item.FullName.ToLower() + "_"
       $name = $item.FullName.ToLower()
       ren $name $temp

       ren $temp $name
   }
0 голосов
/ 11 октября 2010

В PowerShell более логично использовать where вместо if в конвейере:

gci -Recurse Leaflets | 
    ? { $_.Name -ne $_.Name.ToLower()) } | 
    % { ren -NewName $_.Name.ToLower() }
...