2

So I am trying to rename several level1-subfolders from something like "xy_1234" to "1234_xy". So far I've achieved to split the strings into variables, build the new directory-name and rename the directory, but I'm completely failing, when trying to automate the process within a for-loop. Please help.

Get-Item $Path | ForEach ( $a, $b = $Path.split('_') | Rename-Item -NewName { $b + ('_') + $a})
  • Possible duplicate of [Loop through files in a directory using PowerShell](https://stackoverflow.com/questions/18847145/loop-through-files-in-a-directory-using-powershell) – Capricorn May 10 '18 at 21:39

2 Answers2

1
Get-Item $Path | Rename-Item -NewName { 
  $tokens = $_.Name -split '_'         # split the name into tokens
  '{0}_{1}' -f $tokens[1], $tokens[0]  # output with tokens swapped
} -WhatIf

-WhatIf previews the operation.

As you can see, you can do the parsing as part of the script block passed to Rename-Item's -NewName parameter.

Since -NewName only expects the item's file or directory new name (as opposed to the full path), $_.Name is parsed and a transformation of it is (implicitly) output.

Here's a more succinct formulation, inspired by a tip from LotPings:

Get-Item $Path | Rename-Item -NewName { -join ($_.Name -split '(_)')[-1, 1, 0] }

This relies on PowerShell's ability to slice an array by specifying an array (list) of indices: -1, 1, 0 effectively reverses the elements of the array that $_.Name -split '(_)' returns - note the (...) around _, which ensures that instances of _ are included in the array of tokens returned; the unary form of the -join operator then concatenates the reversed array's elements.


Note: I'm assuming that $Path contains a wildcard expression that matches only the directories of interest.

If you need to be explicit about matching directories only, use Get-ChildItem with the
-Directory switch:

Get-ChildItem $Path -Directory

With a wildcard pattern specifically matching the sample name from your question:

Get-ChildItem [a-z][a-z]_[0-9][0-9][0-9][0-9] -Directory
mklement0
  • 382,024
  • 64
  • 607
  • 775
0

I think several subfolders should be caught with a GCI
taking the "xy_1234" to "1234_xy" literal:

Get-ChildItem $Path -Dir | Where-Object Name -match '^([a-z]+)_(\d+)$' |
    Rename-Item -NewName {$_.Name.Split('_')[1,0] -join ('_')} -WhatIf