I have these files
Andromeda (2009)
Mrtik.2004.[director cut]
Jvengers 1999
To move and order folders by alphabetical order I can use
Get-ChildItem -Directory -Path ??* |
Move-Item -Destination {
# Determine the target dir - the input dir's first letter -
# ensure that it exists, and output it.
New-Item -Type Directory -Force (Join-Path $_.Parent.FullName $_.Name[0])
}
this code create A, J, M folders and then moves them in this way
A
| ---> Andromeda (2009)
J
| ---> Jvengers 1999
M
| ---> Mrtik.2004.[director cut]
But I prefer another situation
1999
| ---> Jvengers 1999
2004
| ---> Mrtik.2004.[director cut]
2009
| ---> Andromeda (2009)
any idea?
CodePudding user response:
One way to do it could be using Group-Object
to group all folders by a matched pattern (a 4 number digit in this case - \d{4}
) then you can iterate over the groups and in case needed create the destination folders and move the group of folders to it.
Get-ChildItem -Directory | Group-Object { [regex]::Match($_.Name, '\d{4}').Value } |
ForEach-Object {
# if the pattern was not matched exclude this group
# this is a folder without a year
if(-not $_.Name) { return }
$destination = Join-Path -Path $_.Group[0].Parent -ChildPath $_.Name
if(-not (Test-Path $destination)) {
$destination = New-Item $destination -ItemType Directory
}
# need to exclude those folders from the group that are our destination
# without this you can trriger the following exception:
# `Destination path cannot be a subdirectory of the source ...`
$folders = $_.Group.Where{ $_.FullName -ne $destination }
# if there are no folders to move, go to the next group
if(-not $folders) { return }
Move-Item -LiteralPath $folders -Destination $destination
}