Powershell:根据月份和年份创建文件夹结构,并相应地复制文件

时间:2019-04-22 17:11:43

标签: powershell

我有一个文件夹,其中包含多年来创建的许多文件。让我们将其称为文件夹A,在文件夹A中我有在2012、2013、2014年创建的文件,依此类推,文件将在该文件夹中连续创建。文件夹A下没有结构,只有一堆文件。

任务1:

现在我必须根据月份和年份来复制这些文件,我有一个文件夹B,在此文件夹B中,首先我想按年份创建一个级别,然后在每年下,我将拥有一个文件夹按月,因此文件夹A中的所有文件将根据其创建的日期复制到文件夹B中的每个位置。

--B
---2013
--------Jan
--------Feb
--------Mar
---2014
--------Jan
--------Feb
--------Mar
.......

任务2:

此脚本每天计划运行3次,每次运行时,如果“ 上次修改日期,则必须在源和目标之间比较“ 上次修改日期”。源上的“ strong>”比目标更新,然后将修改后的文件以“原始名称+修改日期”作为新文件名复制到目标。如果文件保持不变,则跳过。

4 个答案:

答案 0 :(得分:1)

最有效的方法是IMO

  • 要从CreationDate年和月创建计算出的属性
  • 按该属性分组
  • 创建目标文件夹(如果不存在)
  • 移动该组的文件

## Q:\Test\2019\04\22\SO_55798207.ps1

$Source = "X:\FolderA"
$Target = "Y:\FolderB"

Push-Location $Source

Get-ChildItem $Source -File |
  Select-Object *,@{n='YearMonth';e={$_.CreationTime.ToString('yyyy\\MMM')}} |
    Group-Object YearMonth | ForEach-Object {
      $NewFolder = Join-Path $Target $_.Name
      If (!(Test-Path $NewFolder)){New-Item $NewFolder -ItemType Directory|Out-Null}
      $_.Group | Copy-Item -Destination $NewFolder
    }
Pop-Location

答案 1 :(得分:0)

这应该满足您的要求:

$Files = Get-ChildItem -Path "C:\FolderA"

Foreach ($File in $Files) {

   $File | Copy-Item -Destination "C:\FolderB\$( $File.LastWriteTime.Year )\$( $File.LastWriteTime.ToString("MMM") )"

}

答案 2 :(得分:0)

好的,这已经被改写了。这是我认为使用这项技术的最有效方法。

$indexFilePath = "C:\Folder B\FileUpdateTracker.Json"

if ((Test-Path -Path $indexFilePath) -eq $false)
{
    [psobject]@{
                LastUpdate = [datetime]::MinValue.Date;
               } | ConvertTo-Json | Out-File -FilePath $indexFilePath -NoClobber
}

$oldFileIndex = Get-Content -Path $indexFilePath | ConvertFrom-Json

$testFiles = @(Get-ChildItem -Path "C:\Folder A" | Where { $_.LastWriteTime.Date -ge $oldFileIndex.LastUpdate })


if ($testFiles.Count -eq 0)
{
    return
}

$fileIndex = [psobject]@{
                            LastUpdate = (Get-Date).Date;
                        }

foreach ($file in $testFiles)
{
    $year = $file.CreationTime.Year
    $month = $file.CreationTime.ToString("MMM")

    $archivePath = "C:\Folder B\$year\$month"

    mkdir -Path $archivePath -ErrorAction SilentlyContinue

    $copiedFileName = $null

    if ((Test-Path "$archivePath\$($file.Name)") -and $file.LastWriteTime.Date -ge $oldFileIndex.LastUpdate)
    {
        $copiedFileName = "$archivePath\$($file.Name.Replace($file.Extension, "_$($file.LastWriteTime.ToString("MM-dd-yy_hh-mm"))$($file.Extension)"))"
    }else{
        $copiedFileName = "$archivePath\$($file.Name)"
    }

    Copy-Item -Path ($file.FullName) -Destination $copiedFileName
}


$fileIndex | ConvertTo-Json | Out-File -FilePath $indexFilePath -Force

答案 3 :(得分:0)

另一种方法是使用BitsTransfer。

$dirA = "C:\Test\A"
$dirB = "C:\Test\B"

$params = Get-ChildItem $dirA -File | foreach {
    $destFile = [IO.FileInfo]("{0}\{1:yyyy}\{1:MMM}\{2}_{3:yyyyMMddhhmmss}{4}" -f $dirB,$_.CreationTime,$_.BaseName,$_.LastWriteTime,$_.Extension)
    if($destFile.Exists) { return }
    $destFile.Directory.Create()
    @{ Src = $_.FullName; Dest = $destFile.FullName }
}

if(!$params) { return }
Start-BitsTransfer -Source $params.Src -Destination $params.Dest -DisplayName "Backup"