Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rename files to lowercase in Powershell

Tags:

I am trying to rename a bunch of files recursively using Powershell 2.0. The directory structure looks like this:

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

I am using the following command:

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

and it seems to rename the files, but complains about the subdirectories:

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

I reload the data monthly using robocopy, but the directories do not change, so I can rename them by hand. Is there any way to get get-children to skip the subdirectories (like find Leaflets -type f ...)?

Thanks.

UPDATE: It appears that the problem is with files that are already all lower case. I tried changing the command to:

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

but now Powershell complains that if is not a cmdlet, function, etc. Can I pipe the output of get-childitem to an if statement?

UPDATE 2: This works:

$files=get-childitem Leaflets -recurse foreach ($file in $files) {     if ($file.name -ne $file.name.ToLower())     {         rename -newname { $_.name.ToLower() }     } } 
like image 632
Ralph Avatar asked Sep 29 '10 14:09

Ralph


1 Answers

Even though you have already posted your own answer, here is a variation:

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

Some points:

  • dir is an alias for Get-ChildItem (and -r is short for -Recurse).
  • % is an alias for ForEach-Object.
  • -cne is a case-sensitive comparison. -ne ignores case differences.
  • $_ is how you reference the current item in the ForEach-Object loop.
  • ren is an alias for Rename-Item.
  • FullName is probably preferred as it ensures you will be touching the right file.

If you wanted to excludes directories from being renamed, you could include something like:

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

Hopefully this is helpful in continuing to learn and explore PowerShell.

like image 89
Goyuix Avatar answered Oct 06 '22 01:10

Goyuix