Powershell:根据创建日期将文件移动到文件夹

5

我不是程序员,但我尝试修改在这里找到的PS脚本,仍然无法得到我想要的结果。对我来说最难的部分是两位数字日期需求(dd)。经过几次尝试,我想寻求帮助。

我有一个包含数百个JPG文件的文件夹。我根据拍摄日期手动将这些JPG文件排序到不同的文件夹中。文件夹示例名称为2015.02.04、2016.10.31、2016.12.01。

1)我想要一个脚本来扫描我的JPG文件夹。 2)对于每个文件,扫描日期 3)如果文件是在2016年6月1日创建的,则将其移动到.\2016.06.01

能帮个忙吗?

$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."

请分享您正在使用的代码。 - user4317867
这段代码几乎实现了我想要的功能。目前,如果它找到了一个2016年6月1日的日期戳,它将把文件移动到.\2016.06.1。我希望它被移动到.\2016.06.01。 - Sab
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 }}

请确保没有命名冲突。 您可以将"c:\test*.jpg"中的"c:\test"更改为您要扫描的路径。 还需要将变量"$des_folder"的值更改为您想要存储匹配图片的目标文件夹。
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 
    }
}

谢谢Paul,但不幸的是这并不是我想要实现的。你的脚本将寻找特定日期并移动那些目标文件。我正在尝试扫描每个文件并根据日期移动它们全部 - Sab
做得好!谢谢您先生 :) - Sab

4
我创建了一个脚本,可以完全满足你在此提出的需求。你可以在GitHub这里找到它,这里会有最新版本的代码。
以下是目前的实现,已编辑为简明扼要,删除了不必要的功能,并根据问题的需求进行优化:
[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
}

请注意,在迭代文件之前,该命令会将文件路径复制到数组中。这对于将文件复制到其当前目录的子目录的情况非常重要,否则Get-ChildItem可能会扫描两次文件,迭代刚刚移动的文件。

0
我想提出这个变体,基于上一个重复项的响应,显示可以选择多个文件,并且删除绝对路径也可以起作用,它将移动当前提示下方的文件,无论文件在哪里。还要添加一个缺少的}。感谢所有为此线程做出贡献的人,这对于组织图片和视频非常有帮助!
$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 
    }
}

0

进一步扩展以覆盖重复内容

$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
虽然这段代码可能解决了问题,但是包括解释它如何以及为什么解决了问题,将有助于提高您的帖子质量,并可能导致更多的赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。请[编辑]您的答案以添加解释并指出适用的限制和假设。 - Brian61354270

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接