Buzz
Buzz

Reputation: 516

Move files into year/month folders based on file name timestamp powershell

I have thousands of files spanning 5 years which I would like to move into year/month folders. The file names all end with

_yyyy_mm_dd_wxyz.dat

I'm looking for ideas on how I can generate such file folders and move the files into the appropriate folders yyyy/mm using the windows command shell.

Upvotes: 1

Views: 1701

Answers (3)

user6811411
user6811411

Reputation:

You'll need a Regular Expression with (capture groups) to extract year/month from the filename.
Assuming the year/month folder should be placed directly in files parent location.

untested with -Version 2

## Q:\Test\2018\07\23\SO_51485727.ps1
Push-Location 'x:\folder\to\start'
Get-ChildItem *_*_*_*_*.dat |
  Where-Object {$_.BaseName -match '_(\d{4})_(\d{2})_\d{2}_[a-z]+$'} | ForEach-Object {
    $TargetDir = "{0}\{1}" -f $Matches[1],$Matches[2]
    if (!(Test-Path $TargetDir)){MD $TargetDir | Out-Null}
    $_ | Move -Destination $TargetDir 
}

Sample tree /f after running the script on my ramdriive:

PS A:\> tree /F
A:.
├───2017
│   └───07
│           test_2017_07_24_xyz.dat
└───2018
    └───07
            test_2018_07_24_xyz.dat

Upvotes: 1

Adam
Adam

Reputation: 4168

At the simplest, I'd do something like the following:

  1. Determine the year and month related to a file
  2. See if a folder exists already. If not, create it
  3. Move the file

Example...

foreach ($file in $(ls .\stuff.txt)) {
    $m = $file.LastWriteTime.Month.ToString("00")
    $y = $file.LastWriteTime.Year
    $dir = "{0}-{1}" -f $y, $m
    New-Item -Name $dir -ItemType directory -ErrorAction SilentlyContinue | Out-Null
    Move-Item -Path $file.Fullname -Destination $dir
}

Upvotes: 0

Henrik Stanley Mortensen
Henrik Stanley Mortensen

Reputation: 1069

I have created this little quick and dirty script. Things have been put in more variables than strictly needed, they could be combined in a single line, but I feel this adds clarity which I hope help you understand what happens.

As a note, I have used the date the item was last written to (created or edited). If you want only the date the file was created and not the time the file was last edited, you could change LastWriteTime to CreationTime

#Load all files from the folder you wish to move on
$items = Get-ChildItem -Path "C:\SomeFolder\RestofPathToYourFiles"

foreach($item in $items) {
    #Creates variables for year, month and day
    $FolderYear = "$($item.LastWriteTime.Year)"
    $FolderMonth = "$($item.LastWriteTime.Month)"
    $FolderDay = "$($item.LastWriteTime.Day)"

    #create variable with the new directory path
    $NewPath = $item.Directory.FullName + "\" + $FolderYear + "\" + $FolderMonth + "\" + $FolderDay

    #create variable with the new full path of the file
    $NewFullPath = $NewPath + "\" + $item.Name

    #test if the folder already is created, if not, create it
    if((Test-Path -Path $NewPath) -eq $false) {
        New-Item -Force -path $NewPath -Type Directory
    }

    #move the item to the new folder
    Move-Item -Path $item.FullName -Destination $NewFullPath -Force
}

Upvotes: 0

Related Questions