Truncating spaces in file names

I am trying to find the files with either leading or trailing spaces. After finding, I would truncate the speces.

I am trying the following code, but apparently it is not working:

Get-ChildItem -Recurse -File | where {($_.Name | out-string).Trim().Length -lt ($_.Name | out-string).Length}

Here the command is running as if there is no where clause at all.

I’d recommend to use a regular expression instead of your “circumstance:wink:

Get-ChildItem -Recurse -File |
Where-Object { _.BaseName -match '^\s+.*\s+’ }

… ooops … forgot the “truncate part” … I assume you want to get rid of the leading and trailing spaces at all … add this:
    |
ForEach-Object{
Rename-Item -Path _ -NewName ((_.BaseName -replace '^\s+' -replace '\s+’) + $_.Extension)
}

Thanks for the response. However, just for my learning, am I making any mistake in the code snippet, I provided?

Get-ChildItem -Recurse -File | where {($_.Name | out-string).Trim().Length -lt ($_.Name | out-string).Length} |
ForEach-Object {Rename-Item -Path $_ -NewName (($_.Name | out-string).Trim())}

 

Did you get the results you expected? If your answer is “No” there seem to be a mistake in your expectations of the results you get from the code you used. To determine the exact output of the code you have to make it visible. Most of the time you can see additional charachters when you output a variable like this “’$($Variable)’” (pay attention to the double and single quotes) … to compare your results you could use a custom object like this:

Result = Get-ChildItem -Recurse -File | 
    ForEach-Object {
        [PSCustomObject]@{
            Name               = .Name
NameString = "’(
.Name | out-string)’"
TrimmedNameString = "’((.Name | out-string).Trim())’"
NameLength = (_.Name | out-string).Length TrimmedNameLength = (
.Name | out-string).Trim().Length
NameLength2 = _.Name.Length TrimmedNameLength2 = _.Name.Trim().Length
}
}
$Result | Format-Table -AutoSize

… as you can see - most of the objects or properties have a length property anyway … you should be able to use that if you need. You should try to write your code as least complex as possible to provide the result you desire.

Out-string adds a newline to each name, so that where clause will be true for every name. Trimming it will remove the newline and will be at least one less in length. Out-string is unnecessary in this case. Name is already a string. Out-string is almost never useful.

'hi there' | out-string | foreach { $_ -replace "`n",'\n' } 

hi there\n

get-childitem | foreach { $_.name.gettype() } 

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
True     True     String                                   System.Object
True     True     String                                   System.Object

Here’s another way:

get-childitem | where { $_.name -ne $_.name.trim() } | 
  Rename-Item -NewName { $_.name.trim() } -whatif