Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Rename Files and Folders with Trailing space

1,203 views
Skip to first unread message

TimA

unread,
Sep 30, 2008, 4:29:01 PM9/30/08
to
This should be simple - I need to write a script to go thru our fileservers
looking for files where the last character is a space or folders where the
last character is a space. For instance "Market Photos 15-19 "

When I attempt to rename one of these I am told the item does not exist so
rename and move fail. I can identify them using dir -force -recurse |
?{$_.Name -match '\s$'}, and I notice that the attrib on the folders is
always DARHS which I cannot change.

I know I can go out to the Windows Command Prompt and use the 8.3 to rename
the folders, but at last count there were over 2500 files and folders like
this - all created by our Mac users - apparently they think a space is a nice
feature at the end of a file or folder name. I've tried VBScript but because
the files and folders are hidden I can't seem to get them to be in the
subFodlers collection.

Any ideas?

TimA

unread,
Sep 30, 2008, 5:01:03 PM9/30/08
to
No it doesn't - here is the text I get:

7> dir -force | ?{$_.Name -match '\s$'}


Directory: Microsoft.PowerShell.Core\FileSystem::O:\Marketing
Graphics\TARGET PACKAGE SHOTS JPG FILES\Files


Mode LastWriteTime Length Name
---- ------------- ------ ----
darhs 12/31/1600 6:00 PM <DIR> Files for Boards 15-19


8> rename-item "Files for Boards 15-19 " "Files for Board 15-19X"
Rename-Item : Cannot rename because item at 'Files for Boards 15-19 ' does
not exist.
At line:1 char:12
+ rename-item <<<< "Files for Boards 15-19 " "Files for Board 15-19X"
9> rename-item "Files for Boards 15-19 " "Files for Board 15-19X" -force
Rename-Item : Cannot rename because item at 'Files for Boards 15-19 ' does
not exist.
At line:1 char:12
+ rename-item <<<< "Files for Boards 15-19 " "Files for Board 15-19X" -force

Sorry about the bad formatting.

As to recreating I've just created a folder from DOS using md Test+ALT255.
The alt+255 creates the space for me and recreates the issue.

Thanks!

"Keith Hill [MVP]" wrote:

> Does it work if you use the -force parameter on rename-item? Sorry, but a
> few attempts to create a filename ending with a space have not been
> successful. So I can't test this very easily.
>
> --
> Keith
>
> "TimA" <Ti...@discussions.microsoft.com> wrote in message
> news:15335DA5-21AE-471F...@microsoft.com...

Kiron

unread,
Oct 1, 2008, 10:57:31 PM10/1/08
to
What does this return?

dir -force -recurse | ? {$_.Name -match '\s$'} | % {[int]$_.name[-1]}

--
Kiron

TimA

unread,
Oct 2, 2008, 11:48:13 AM10/2/08
to
It returns 32, which is the ascii equiv of the space. So I guess that
confirms the unprintable character is a space.

Joel (Jaykul) Bennett

unread,
Oct 2, 2008, 12:33:09 PM10/2/08
to
Well, alt+255 isn't a plain old space, that's for sure. But I *can*
duplicate your error that way:

[113]: echo "foo" > "This is a test"
[114]: cmd /c move "This is a test" "This is a test " # using ALT+255
at the end
[115]: dir -force -recurse | ? {$_.Name -match '\s$'} | % { "'$
($_.Name)'" }
'This is a test '


I admire the problem :) My first thought was to just pipe the
FileInfo in:

[116]: dir -force -recurse | ? {$_.Name -match '\s$'} | rename-item -
new {$_.Name.TrimEnd()}
Rename-Item : Cannot rename because item at 'Microsoft.PowerShell.Core
\FileSystem::C:\Documents and Settings\us321339\My Documents
\WindowsPowershell\This is a test ' does not exist.
At line:1 char:61
+ dir -force -recurse | ? {$_.Name -match '\s$'} | rename-item <<<< -
new {$_.Name.TrimEnd()}

[117]: dir -force -recurse | ? {$_.Name -match '\s$'} | move-item -
dest {$_.Name.TrimEnd()}
Move-Item : Cannot move item because item at 'Microsoft.PowerShell.Core
\FileSystem::C:\Documents and Settings\us321339\My Documents
\WindowsPowershell\This is a test ' does not exist.
At line:1 char:59
+ dir -force -recurse | ? {$_.Name -match '\s$'} | move-item <<<< -
dest {$_.Name.TrimEnd()}


Then I thought I'd try wildcards:

[118]: dir -force -recurse | ? {$_.Name -match '\s$'} | % { move-item
"$($_.Name.TrimEnd())*" $_.Name.TrimEnd() }
Move-Item : Cannot move item because item at 'C:\Documents and Settings
\us321339\My Documents\WindowsPowershell\This is a test ' does not
exist.
At line:1 char:63
+ dir -force -recurse | ? {$_.Name -match '\s$'} | % { move-item <<<<
"$($_.Name.TrimEnd())*" $_.Name.TrimEnd() }


Finally, I thought, well, if I created this in CMD, I can uncreate it
in CMD:

[119]: dir -force -recurse | ? {$_.Name -match '\s$'} | % { cmd /c
move "$($_.Name)" "$($_.Name.TrimEnd())" }

Sure enough, that worked.
--
Joel "Jaykul" Bennett

TimA

unread,
Oct 2, 2008, 1:27:00 PM10/2/08
to
I really thought this was going to work because I know I can use cmd and
using the shortname's rename these folders, but it appears the Mac creators
of these files and folders have an additional twist as mentioned in the
original post. These Folders are marked DARHS - so not only hidden but
System as well. Move cannot work on them it appears and I can't figure out
how to remove those attributes.

I like your solution and I think it's on the right track now how to deal
with those attributes. I'm really starting to dislike Macs.

TimA

unread,
Oct 2, 2008, 4:46:11 PM10/2/08
to
Just a little extra information I just found, when I look at attributes
rather than mode this is what I get

70> dir -force | fl Name, Attributes


Name : Files for Boards 1-10
Attributes : Directory

Name : Files for Boards 11-14
Attributes : Directory

Name : Files for Boards 15-19
Attributes : -1

Name : LOGO OPTIONS_1-2
Attributes : Directory

Name : PDFs for HPs
Attributes : Directory

Name : .DS_Store
Attributes : Archive

Name : ._Files for Boards 1-10
Attributes : Archive

Name : ._Files for Boards 11-14
Attributes : Archive

I notice that the folder with the space at the end does not have a valid
entry for attributes. Perhaps this is causing some of the issue.

RickB

unread,
Oct 2, 2008, 5:32:51 PM10/2/08
to

There is a parellel thread that has almost exactly this problem.
"Can't rename files with certain characters in them."
The answer was this.

(dir ".\$srcName" -literalpath).moveto(".\$destName")

Perhaps it works here too??

Kiron

unread,
Oct 3, 2008, 8:43:24 AM10/3/08
to
Alt+255 produces a NBSP.
On my system (Vista SP1) the command...

ls -fo -r | ? {$_.name -match '\s$'} | % {[int]$_.name[-1]}

# ...returns 160, and...

ls -fo | ? {$_.name -match '\u00a0$'}

# ...lists the items whose name end in a NBSP

# set the Archive/Directory attribute and clear all others with this:

ls -fo | ? {$_.name -match '\s$'} | % {
if (!$_.psIsContainer) {$_.attributes = 32} else {$_.attributes = 16}
}

# But to rename the items I did this from the CMD console:
# [The space after the * is a NBSP (Alt+255)]

for /R /D %A in ("* ") do ren "%~fA" %~nA
for /R %A in ("* ") do ren "%~fA" %~nA
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

IO.FileAttributes

Name Int
---- ---
ReadOnly 1
Hidden 2
System 4
Directory 16
Archive 32
Device 64
Normal 128
Temporary 256
SparseFile 512
ReparsePoint 1024
Compressed 2048
Offline 4096
NotContentIndexed 8192
Encrypted 16384

--
Kiron

TimA

unread,
Oct 3, 2008, 11:02:01 AM10/3/08
to
Unfortunately same issue - PowerShell cannot locate the file -

28> ls -fo | ? {$_.name -match '\s$'} | % { if (!$_.psIsContainer)

{$_.attributes = 32} else {$_.attributes = 16}}

Exception setting "Attributes": "Could not find file 'Files for Boards 15-19
'."
At line:1 char:94
+ ls -fo | ? {$_.name -match '\s$'} | % { if (!$_.psIsContainer)

{$_.attributes = 32} else {$_.a <<<< ttributes = 16}}

That space is giving PS fits. Since -1 is not a valid attribute I am not
sure how I can change that unless I can grab a different file handle in PS.

When I tried

> for /R /D %A in ("* ") do ren "%~fA" %~nA

CMD seems to strip the space off of the file before doing anything as here
is the output

O:\Marketing Graphics\TARGET PACKAGE SHOTS JPG FILES\Files>ren "O:\Marketing
Gra
phics\TARGET PACKAGE SHOTS JPG FILES\Files\Files for Boards 15-19" Files for
Boards 15-19
The syntax of the command is incorrect.

I notice there is no space between the 19 and the quote.

I've tried the PS community extensions and the GetShortPath command cannot
latch onto the file to get the short path. I thought if I could script like
this cmd /c ren $ShortName "$LongName" I might be able to get it to work but
I can't get the Shortname in PS.

I feel like I am missing something very obvious here.

RickB

unread,
Oct 3, 2008, 12:00:00 PM10/3/08
to
> Perhaps it works here too??- Hide quoted text -
>
> - Show quoted text -

I suppose it helps to have the syntax correct.

(dir -literalpath ".\$srcName").moveto(".\$destName")

TimA

unread,
Oct 3, 2008, 12:23:00 PM10/3/08
to
"RickB" wrote:

> I suppose it helps to have the syntax correct.
>
> (dir -literalpath ".\$srcName").moveto(".\$destName")
>

Thought it looked odd :)
Unfortunately no luck. Nothing seems to allow PS to grab the space and
treat it as part of the filename -

49> (dir -literalpath ".\$srcName").moveto(".\$destName")
Get-ChildItem : Cannot find path 'O:\Marketing Graphics\TARGET PACKAGE SHOTS
JPG FILES\Files\Files for Boards 15-19 ' because it does not exist.
At line:1 char:5
+ (dir <<<< -literalpath ".\$srcName").moveto(".\$destName")
You cannot call a method on a null-valued expression.
At line:1 char:39
+ (dir -literalpath ".\$srcName").moveto( <<<< ".\$destName")

I can't even figure out how the Mac clients did this to duplicate. It
seems to have been 10.4 or earlier clients because none of the 10.5 clients
can do this. Unfortunately the one 10.4 we have left is in Germany at the
moment so I can't confirm with that one.

David Trimboli

unread,
Oct 3, 2008, 1:16:17 PM10/3/08
to

I don't know how to deal with this in PowerShell, but I know how to fix
it with CMD: http://support.microsoft.com/kb/315226

Instead of "C:\Folder\File with space at end.txt ", use
"\\?\C:\Folder\File with space at end.txt ". You should be able to
delete bad file names this way.

--
David
Stardate 8757.6

Kiron

unread,
Oct 3, 2008, 1:21:37 PM10/3/08
to
I can't explain why you can't set attributes through PowerShell, could be because of different OS. It's also weird, that in my tests the NBSP is not stripped from the first arg if it's quoted, but I didn't test against files with spaces -normal spaces- in them. Not quoting the second arg -new name- strips the NBSP, but it won't work with names that include spaces, it causes the wrong syntax error unless the second arg is quoted, however, if the second arg is quoted the NBSP is included, along with the spaces between words, and the purpose is defeated. The second arg can't be a path, it has to be the new name.

for /R %A in ("* ") do ren "%~A" %~nA

ren "C:\temp\d1\f1 n1 " f1 n1
The syntax of the command is incorrect.

for /R %A in ("* ") do ren "%~fA" "%~nA"

ren "C:\temp\d1\f1 n1 " "f1 n1 "

in CMD you can get the short path/name like this but the NBSP remains in the longname
for /R %A in ("* ") do ren %~sA %~snA

ren C:\temp\d1\F1N1~1 F1N1~1

for /R %A in ("* ") do ren %~sA "%~nA"

ren C:\temp\d1\F1N1~1 "f1 n1 "

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# in PowerShell you can get the short path/name like this, and it is
# a great idea Tim, it works here, hope it will for you

$fso = new-object -c scripting.filesystemobject
ls -fo | ? {$_.name -match '\s$'} | % {$fso.getFile($_.fullname).shortPath}
ls -fo | ? {$_.name -match '\s$'} | % {$fso.getFile($_.fullname).shortName}

# this works against ReadOnly, Hidden, System, Archive files
# and ReadOnly, Hidden, System, Directory folders, one problem, it won't
# work recursively, you'd have to pushd/popd and execute accordingly

ls -fo | ? {$_.name -match '\s$'} | % {
if ($_.psIsContainer) {
rni $fso.getFolder($_.fullname).shortPath ($_.name -replace '\s$')
} else {
rni $fso.getFile($_.fullname).shortPath ($_.name -replace '\s$')
}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

If the above doesn't work in your system maybe this thread gives you another idea, it mentions FreeCommander, I've never used it though:
http://www.howtogeek.com/forum/topic/help-renaming-after-alt255

--
Kiron

TimA

unread,
Oct 3, 2008, 1:33:02 PM10/3/08
to

"David Trimboli" wrote:
> Instead of "C:\Folder\File with space at end.txt ", use
> "\\?\C:\Folder\File with space at end.txt ". You should be able to
> delete bad file names this way.
>
> --
> David
> Stardate 8757.6
>

Yeah I stumbled on that too and it does work but I couldn't get it to work
in a powershel script. With 2500 files and the possibility that the users
will continue to do it, I need to figure out a scriptable method.

David Trimboli

unread,
Oct 3, 2008, 4:38:12 PM10/3/08
to

Oh, you can script that in CMD. Mind you, I haven't tested this. X:\ is
the root directory of a recursive search for files with names or
extensions ending in a single space. The script doesn't check for
multiple trailing spaces.

setlocal enabledelayedexpansion enableextensions
for /r X:\ %%i in (*) do (
set rename=no
set name=%~ni
set extension=%~xi
set filename=!name!!extension!
if "!name~-1!" equ " " (
set name=!name~0,-1!
set rename=yes
)
if "!extension~-1!" equ " " (
set extension=!extension~0,-1!
set rename=yes
)
if "!rename!" equ "yes" ren "\\?\%%i" "!name!!extension!"
)
endlocal

--
David
Stardate 8757.9

0 new messages