I am not a big fan of file names with spaces. I realize they are easy to read and obviously much more "natural", but they are simply a royal pain to deal with, especially when working from a command prompt or PowerShell. So naturally the solution is to rename these files and replace the space with something else like an underscore (_). Here's how I'll tackle this using Windows PowerShell.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
First, I need to isolate files that have a space in the name. For that I can use a regular expression pattern with the -Match operator.
[cc lang="DOS"]
PS C:\> dir e:\test | where {-Not $_.PsIscontainer -AND $_.name -match "\s"}
Directory: E:\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 10/12/2011 8:56 AM 31708 my processes.txt
-a--- 10/12/2011 8:56 AM 26662 My services.txt
-a--- 2/15/2011 7:36 AM 178764 net error codes.txt
-a--- 11/4/2010 9:59 PM 246534 Sample ebook.pdf
[/cc]
I'm filtering out folders for now but the same techniques apply. PowerShell has the Rename-Item cmdlet (it has an alias of ren). All I need to do is pipe these files to Rename-Item and give each file a new name. Because I want to use the existing name as the basis for the new name, I'll have to use a ForEach-Object construct.
[cc lang="PowerShell"]
dir e:\test | where {-Not $_.PsIscontainer -AND $_.name -match "\s"} | foreach {
$New=$_.name.Replace(" ","_")
Write-Host $new -fore Cyan
[/cc]
I'll take each file and define a new name by invoking the Replace() method on the name property (which is a string), replacing the space with a _. Now I can use this value as the new name with Rename-Item.
[cc lang="PowerShell"]
Rename-Item -path $_.Fullname -newname $new -passthru -whatif
}
[/cc]
Rename-Item supports -Whatif so I can double check the files that would be renamed. I'll also use -passthru so I can see the results. Here's the final result.
[cc lang="DOS"]
PS C:\> dir e:\test | where {-Not $_.PsIscontainer -AND $_.name -match "\s"} | foreach {
>> $New=$_.name.Replace(" ","_")
>> Rename-Item -path $_.Fullname -newname $new -passthru
>> }
>>
Directory: E:\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 10/12/2011 8:56 AM 31708 my_processes.txt
-a--- 10/12/2011 8:56 AM 26662 My_services.txt
-a--- 2/15/2011 7:36 AM 178764 net_error_codes.txt
-a--- 11/4/2010 9:59 PM 246534 Sample_ebook.pdf
PS C:\>
[/cc]
And there it is! Because I'm using -passthru, I omitted the Write-Host command. Be sure to read help and examples for Rename-Item and test your code on a small sample.