5

I'm not a coder but I've still attempted tweaking PS scripts found here and still can't get the behavior I desire. The tough part for me has been the 2 digit Day requirement (dd). After several noob attempts I would like some help.

I have a folder that contains hundreds of JPG's. I manually sort these JPG's into folders based on the date taken. Folder name examples are 2015.02.04, 2016.10.31, 2016.12.01.

1) I would like a script to scan my JPG folder. 2) For each file, scan the date 3) If the file was created June 1st, 2016 then it will be moved to .\2016.06.01

Help a brother out?

$Filepath = ""
$file = ""
$date  = ""
$month   = ""
$year    = ""
$MonthPath   = ""

$FilePath = Read-Host "Place the directory which contains the files."

Write-Warning "Note: This action can take several minutes, depending on the amount of files in $FilePath."

get-childitem $FilePath | % {

  $file = $_.FullName 
    $date = Get-Date ($_.LastWriteTime)

  $month = $date.month
  $year = $date.year
  $day = $date.day
    $MonthPath = "$FilePath\$year.$month.$day"
    Write-Verbose "month = $month"
    Write-Verbose "Date = $date"
    Write-Verbose "year = $year"
    Write-Verbose "FilePath = $FilePath" 
    Write-Verbose "Filename = $file"
    Write-Verbose "MonthPath = $MonthPath"

    if(!(Test-Path -Path "$MonthPath" )){
        Write-Verbose "Creating log location $MonthPath."
        #Write-Host -backgroundcolor green -ForegroundColor black "Creating log location $MonthPath."
        Write-Verbose "MonthPath inside path test = $MonthPath"
        New-Item -ItemType directory -Path $MonthPath | Out-null
    }
    ELSE {
        #Write-Host -backgroundcolor green -ForegroundColor black "Log location exists already exist $MonthPath"
        Write-Verbose "Log location exists already exist $MonthPath" 
        }
    move-item "$file" "$MonthPath" | Out-null
}

Write-Warning "All files are sorted now based upon year and month."
2
  • Please share the code you are working with. Commented Oct 9, 2016 at 0:09
  • This code almost achieves what I'm after. Currently, if it finds a date stamp of June 1st, 2016 it'll move the file to .\2016.06.1. I want it moved to .\2016.06.01. Commented Oct 9, 2016 at 3:16

4 Answers 4

10
[DateTime]$start_time="2016-6-1 00:00:00"
[DateTime]$end_time="2016-6-1 23:59:59"
$des_folder = "C:\test\2016.06.1"

Get-ChildItem c:\test\*.jpg -Recurse | foreach {if($_.lastwritetime -ge $start_time -and $_.lastwritetime -le $end_time) { move-item $_.fullname $des_folder }}

Please ensure there is no name conflict . You may change"c:\test" in "c:\test*.jpg" to the path you want to scan . Also the value of variable "$des_folder" to the destination folder you want to store the matched pictures .

EDIT:

Get-ChildItem c:\test\test2\*.jpg -Recurse | foreach { 
$x = $_.LastWriteTime.ToShortDateString()
$new_folder_name = Get-Date $x -Format yyyy.MM.dd
$des_path = "c:\test\test2\$new_folder_name"

if (test-path $des_path){ 
    move-item $_.fullname $des_path 
    } else {
    new-item -ItemType directory -Path $des_path
    move-item $_.fullname $des_path 
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Paul, but unfortunately this isn't quite what I'm trying to achieve. Your script will hunt for a particular date and move just those targeted files. I am trying to scan each file and move them all according to date.
Nailed it! Thank you sir :)
4

I ended up creating a script that does exactly what you're asking for here. You can find it in GitHub here, which will have the latest version of the code.

Here is the current implementation, edited for conciseness, removed unnecessary features, and tailored to the question's needs:

[string] $SourceDirectoryPath = 'C:\FilesToMove'
[string] $TargetDirectoryPath = 'C:\SortedFiles'

[System.Collections.ArrayList] $filesToMove = Get-ChildItem -Path $SourceDirectoryPath -File -Force -Recurse

$filesToMove | ForEach-Object {
    [System.IO.FileInfo] $file = $_

    [DateTime] $fileDate = $file.LastWriteTime
    [string] $dateDirectoryName = $fileDate.ToString('yyyy.MM.dd')
    [string] $dateDirectoryPath = Join-Path -Path $TargetDirectoryPath -ChildPath $dateDirectoryName

    if (!(Test-Path -Path $dateDirectoryPath -PathType Container))
    {
        Write-Verbose "Creating directory '$dateDirectoryPath'."
        New-Item -Path $dateDirectoryPath-ItemType Directory -Force > $null
    }

    [string] $filePath = $file.FullName
    Write-Information "Moving file '$filePath' into directory '$dateDirectoryPath'."
    Move-Item -Path $filePath -Destination $dateDirectoryPath
}

Note that it copies the file paths into an array before iterating over them. This is important for the cases where you are copying files to subdirectories of their current directory, otherwise Get-ChildItem could scan files twice, iterating over files that it just moved.

Comments

0

Expanded more to cover off duplicates

$jpg_files = Get-ChildItem "F:\*.jpg" -Recurse
foreach ($jpg in $jpg_files){

$x = $jpg.LastWriteTime.ToShortDateString()
$new_folder = Get-Date $x -Format yyyy-MM-dd
$des_path = "F:\Photos\$($new_folder)"

if (Test-Path $des_path){
    if (Test-Path "$($des_path)\$($jpg.Name)"){
        $index = 1
        do {
            $new_name = $des_path + "\" + $jpg.BaseName + " ($($index))" + $jpg.Extension
            $index++
        } While(Test-Path $new_name)

        move-item $jpg.fullname -destination $new_name
    }else {
        move-item $jpg.fullname $des_path
    }
}
else {
    new-item -ItemType directory -Path $des_path
    move-item $jpg.fullname $des_path 
}

1 Comment

While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply.
0

I would like to propose this variant based on last response for duplicates showing that multiple files can be selected and also that removing the absolute paths works and it will move the files that are bellow of your current prompt no mathers where the file is. Also add a missing }. Thanks to all that contributes to this thread, this helps a lot to organize the pictures and video!

$files = Get-ChildItem "*.jpg","*.mp4" -Recurse
foreach ($file in $files) {

$x = $file.LastWriteTime.ToShortDateString()
$new_folder = Get-Date $x -Format yyyy-MM
$des_path = "$($new_folder)"

if (Test-Path $des_path) {
        if (Test-Path "$($des_path)\$($file.Name)") {
            $index = 1
            do {
                $new_name = $des_path + "\" + $file.BaseName + " ($($index))" + $file.Extension
                $index++
            } While(Test-Path $new_name)

            move-item $file.fullname -destination $new_name
        }else {
            move-item $file.fullname $des_path
        }
    }
    else {
        new-item -ItemType directory -Path $des_path
        move-item $file.fullname $des_path 
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.