使用Powershell将新文件从外部HD复制到桌面



感谢您阅读我的帖子和您的建议:) 场景是,我的桌面上内置了一个高清,我在那里收集了多年的文件。所以有一天我备份了外部高清,然后我旅行并继续从手机等收集照片。

从那以后,我在桌面上更改了很多文件夹结构,因此我无法一对一比较文件夹/文件。

目标显然是,将我的外部HD上的所有文件复制到我的内部HD中,全部放在名为" 2SORT"的文件夹中。

我发现了一个更快的比较对象版本(见评论(,但结果不正确,它会复制很多已经存在的文件。

这是我在Powershell中得到的:

cls
$path_desktop = 'C:FilesMediaBilder'
$path_external = 'E:Bilder'
$path_destination = 'C:FilesMediaBilder2SORT'
$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

}

如果这是您经常做的事情,我建议重构以使用robocopy。第一次运行后,任何后续运行都会快得多,因为robocopy旨在执行这些任务。无论您使用什么工具,第一次运行都会很慢。

Compare-Object将比较属性值。通过传递一堆值,它将有更多的工作要做。此外,在运行此函数时,您实际上并没有移动任何文件,因此如果取消此操作,则脚本不会移动任何内容。如果您只想比较每个文件名的列表并复制它们是否存在于$ref但不是$com,您可以限制您获得的属性,并像下面一样手动迭代/移动每个属性$ref。

如果您想继续使用Compare-Object请查看它的-Property参数来限制它正在比较的属性数量。

$path_desktop = 'C:FilesMediaBilder'
$path_external = 'E:Bilder'
$path_destination = 'C:FilesMediaBilder2SORT'
$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并迭代差异(

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

若要查看 Get-ChildItem 返回哪些属性,请将其传递到"获取成员类型属性"中

Get-ChildItem -path $path_desktop -Recurse -File | Get-Member -Type Properties

最后,我不得不通过MD5-Hash比较文件,因为我得到了许多重复项,只是不同的"最后写入时间":

cls
$path_desktop = 'C:FilesMediaBilder'
$path_external = 'C:FilesMediaext'
$path_destination = 'C:FilesMediaBilder2SORT'
$path_intcsv = 'C:FilesMediaBilderinthash2.csv'
$path_extcsv = 'C:FilesMediaBilderexthash2.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
}

最新更新