Ceus
Ceus

Reputation: 9

Powershell batch renaming files with index

for a personal project I want to prefix folder and file names with an index. The goal is to have every childitem name remain the same except for the prefix.

My current Script looks as follows:

$vaultDir = $args[0]
$path = Get-ChildItem -Path $vaultDir -Depth 0
ForEach($childObject in $path){
    $index = '{0:d3}' -f $path.IndexOf($childObject)
    $currentFolderName =  $childObject.ToString() | out-string | select-string -pattern '[^\\]+$'
    $newName=($index.ToString()+'-'+$currentFolderName.Matches.value)
    $childObject.FullName |rename-Item -newname {$_.Name -replace '.*', $newName} -whatif
}

The $newName is set correctly. Now I want to iterate through the childitems and rename them.

But honestly I do not get how the rename-item function works.

The -whatif result seems to work(the test folders are named asdfg and tyui):

What if: Performing the operation "Rename Directory" on target "Item: C:\Users\mon0\Documents\Script\kekw\asdfg Destination: C:\Users\mon0\Documents\Script\kekw\000-asdfg
".
What if: Performing the operation "Rename Directory" on target "Item: C:\Users\mon0\Documents\Script\kekw\tyui Destination: C:\Users\mon0\Documents\Script\kekw\001-tyui
".

but when I remove it I get the following error message:

Line |
  19 |  … ject.FullName |rename-Item -newname {$_.Name -replace '.*', $newName}
     |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The filename, directory name, or volume label syntax is incorrect.

Rename-Item: C:\Users\mon0\Documents\Script\Batch-Rename.ps1:19:28
Line |
  19 |  … ject.FullName |rename-Item -newname {$_.Name -replace '.*', $newName}
     |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The filename, directory name, or volume label syntax is incorrect.

Any ideas ?

Upvotes: 0

Views: 789

Answers (1)

mklement0
mklement0

Reputation: 437197

Your immediate problem is the - unnecessary - use of Out-String:

Unfortunately, Out-String invariably appends a trailing newline to the stringified output - see GitHub issue #14444 for a discussion of this problematic behavior - which is what causes your problem: what the Select-String regex, '[^\\]+$', matches includes the CR of that trailing newline on Windows.

Therefore, the immediate fix is to simply remove the Out-String call.

However, your code can be greatly simplified:

$vaultDir = $args[0]
$index = @{ Value = 0 }
Get-ChildItem -Path $vaultDir |
  Rename-Item -NewName { '{0:d3}-{1}' -f ++$index.Value, $_.Name } -WhatIf

Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.

For an explanation of the technique used above, see this answer.

Upvotes: 0

Related Questions