如何根据文件年龄删除重复项

时间:2018-03-21 14:58:55

标签: windows powershell

我需要删除重复文件,只保留原始文件(最旧的文件)。我需要它来处理目录,并能够设置路径,即E:media /,目录将有不重复的文件(我需要保留那些)和重复文件(有时多于1个重复)。

我已经能够将基于哈希的脚本组合在一起,但是如果我设置路径并且它不能与目录一起使用,我似乎无法正常工作。

$files = Get-ChildItem -File | 
            Select-Object FullName, LastWriteTime, @{n="hash";e= {(Get-FileHash $_).Hash}} | 
                Sort-Object Hash,LastWriteTime

for ($i=1; $i -lt $files.count; $i++){ 
     Write-Host $i
     If ($files[$i].hash -eq $files[$i-1].hash){ 
              Remove-Item -Path $files[$i].fullname
     }
}

我改变了

$files=Get-ChildItem E:/media -File

 Get-ChildItem E:/media -File

但不起作用,我无法弄清楚如何让它在目录中工作,它只能在所述文件夹中工作,我有10000个文件夹我需要整理。

我很难过,并会欣赏正确方向的任何指示,谢谢

2 个答案:

答案 0 :(得分:1)

我首先找到所有重复的对,然后忽略其余的对。然后浏览每对/一组重复项并对其进行排序:

# Find all groups of duplicate files
$DuplicateGroups = Get-ChildItem E:\media -Recurse -File |Group {
  (Get-FileHash $_.FullName).Hash
} |Where-Object Count -gt 1

# Go through each group
foreach($Duplicates in $DuplicateGroups){
  # Remove all files except for the oldest one
  $Duplicates.Group |Sort-Object LastWriteTime |Select -Skip 1 |Remove-Item
}

答案 1 :(得分:0)

为了简化 Mathias R. Jessen的回答,您可以在一行中完成所有工作:

Get-ChildItem E:\Media -Recurse -File | # Recursively find files
    Group-Object -Property {(Get-FileHash $_.FullName).Hash} | # Group by file hash
        Where-Object Count -gt 1 | # Groups with more than one item contain duplicates
            ForEach-Object { $_.Group } | # 'Expand' groups with duplicates
                Sort-Object -Property LastWriteTime | # Oldest item will be first
                    Select-Object -Skip 1 | # Skip first (oldest) item
                        Remove-Item -Force # Remove duplicate files

以上内容将从目录树中的任何位置删除重复项。如果你只想删除同一目录中的重复项,这个稍微修改过的代码(按哈希包含目录分组)将起到作用:

Get-ChildItem -Path "E:\Media" -File -Recurse |
    Group-Object -Property DirectoryName, {(Get-FileHash $_.FullName).Hash} |
        Where-Object Count -gt 1 |
            ForEach-Object { $_.Group |
                Sort-Object -Property LastWriteTime |
                    Select-Object -Skip 1 |
                        Remove-Item -Force
        }