Скопируйте новые файлы с внешнего HD на рабочий стол с помощью Powershell - PullRequest
0 голосов
/ 21 января 2020

Спасибо, что прочитали мой пост и ваши советы :) Сценарий таков, что у меня есть HD, встроенный в мой рабочий стол, где я собирал файлы в течение многих лет. Итак, однажды я сделал резервную копию на внешнем HD-диске, который затем отправился в путешествие и продолжал собирать фотографии со своего телефона и т. Д. c.

С тех пор я много раз менял структуру папок на рабочем столе, поэтому Я не могу сравнить папки / файлы 1on1.

Очевидно, что цель состоит в том, чтобы все новые файлы, которые находятся на моем внешнем HD, копировались на мое внутреннее HD, все они помещались в папку. назван как '2SORT'.

Я нашел более быструю версию объекта сравнения (см. комментарии), но результаты неверны, он скопирует много файлов, которые уже существуют.

Вот что я получил в Powershell:

cls

$path_desktop = 'C:\Files\Media\Bilder'
$path_external = 'E:\Bilder'
$path_destination = 'C:\Files\Media\Bilder\2SORT'

$ref = Get-ChildItem -path $path_desktop -Recurse -File
$com = Get-ChildItem -path $path_external -Recurse -File

$file_Diffs = Compare-Object -ReferenceObject $ref -DifferenceObject $com | Where { $_.SideIndicator -eq '=>' }

$file_Diffs | 
foreach {

	$copyParams = @{}
	$copyParams.Path = $_.InputObject.FullName
	$copyParams.Destination = "$path_destination\" + $_.InputObject.Name

	copy-Item @copyParams -force -PassThru | Write-Host
     
}

Ответы [ 2 ]

1 голос
/ 22 января 2020

Если вы регулярно этим занимаетесь, я бы рекомендовал рефакторинг для использования robocopy. После первого запуска любые последующие запуски будут намного быстрее, потому что robocopy был разработан для выполнения этих задач. Первый запуск будет медленным независимо от того, какой инструмент вы используете.

Compare-Object собирается сравнить значения свойств. Передавая кучу ценностей, у нее будет больше работы. Кроме того, вы не перемещаете никаких файлов во время работы этой функции, поэтому, если эта операция отменена, ваш сценарий ничего не перемещал. Если вы просто хотите сравнить список имен файлов в каждом и скопировать, если они существуют в $ref, но не в $com, вы можете ограничить свойства, которые вы получаете, и перебирать / перемещать каждое из них в $ ref вручную, как я. ниже.

Если вы хотите продолжать использовать Compare-Object, посмотрите на его -Property параметр, чтобы ограничить число сравниваемых свойств.

$path_desktop = 'C:\Files\Media\Bilder'
$path_external = 'E:\Bilder'
$path_destination = 'C:\Files\Media\Bilder\2SORT'

$ref = Get-ChildItem -path $path_desktop -Recurse -File | select name, fullname
$com = Get-ChildItem -path $path_external -Recurse -File | select name, fullname

$ref | 
foreach {
    if ($_.name -in $com | select -ExpandProperty name)
        continue;

    --Copy file
}

Вы также можете получить другие свойства файла при необходимости вы можете использовать эти свойства, когда будете выполнять сравнение (либо «вручную», либо с помощью compare-object и итерируя по diff)

Get-ChildItem -path $path_desktop -Recurse -File | select Name,fullname, LastWriteTime

, чтобы увидеть, какие свойства возвращает Get-ChildItem, передать в свойствах Get-Member -Type

Get-ChildItem -path $path_desktop -Recurse -File | Get-Member -Type Properties
0 голосов
/ 22 января 2020

В итоге мне пришлось сравнивать файлы по их MD5-Ha sh, потому что я получил много дубликатов только с разным 'lastwritetime':

cls

    $path_desktop = 'C:\Files\Media\Bilder\'
    $path_external = 'C:\Files\Media\ext'
    $path_destination = 'C:\Files\Media\Bilder\2SORT'
    $path_intcsv = 'C:\Files\Media\Bilder\inthash2.csv'
    $path_extcsv = 'C:\Files\Media\Bilder\exthash2.csv'

    $count=0
    $res = @()

    Get-ChildItem -path $path_desktop -Recurse -File | % {
    	
    	Write-Host ($count++)
    	$hash = Get-FileHash $_.FullName -Algorithm MD5
    	$res += New-Object PSObject -Property @{Hash=$hash.Hash; FullName=$_.FullName}
    }

    $res | epcsv -path $path_intcsv -NoTypeInformation

    $count=0
    $res = @()

    Get-ChildItem -path $path_external -Recurse -File | % {
    	Write-Host ($count++)
    	$hash = Get-FileHash $_.FullName -Algorithm MD5
    	$res += New-Object PSObject -Property @{Hash=$hash.Hash; FullName=$_.FullName}
    }

    $res | epcsv -path $path_extcsv -NoTypeInformation
    	

    $int = Import-Csv $path_intcsv 
    $ext = Import-Csv $path_extcsv
      
    $IntHash = @{}          
    $ExtHash = @{}          
    $DifHash = @{}          
     
    $int | ForEach-Object {
    	$newKey=$_.Hash
    	if (!$IntHash.ContainsKey($newKey)) {
    		$IntHash.Add($newKey, $null)
    	}
    }               

    $ext | ForEach-Object {
    	$newKey=$_.Hash
    	if (!$ExtHash.ContainsKey($newKey)) {
    		$ExtHash.Add($newKey, $_.FullName)
    	}
    }  

    ForEach ($key in $ExtHash.Keys) {            
    	If (!$IntHash.ContainsKey($key)) {            
    		$DifHash.Add($key, $ExtHash[$key])
    	}    
    }     

    #check folder exists
    if (-not (test-path $path_destination)) { 
    		$make = new-item -ItemType directory -Path $path_destination
    }      

    #copy files
    ForEach ($key in $DifHash.Keys) {
    	$fullname = $DifHash[$key]
    	Copy-Item $fullname -Destination $path_destination -Force
    }
...