Home > Enterprise >  Move folders to other folders sorted by year
Move folders to other folders sorted by year

Time:03-28

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
}
  • Related