John Adam1
John Adam1

Reputation: 55

Compare files sizes and move to a folder

in the script below I'm searching for files of the same size and moving them to the "C:\files_compared", the problem is that I want to let one file of the compared files where it is ("C:\folder1") and move only the others to the "C:\files_compared".

It doesn't matter the name of the file that stays in the original folder, could be any of the compared ones, as long as it is one of the ones that are in the size comparison criteria.

$allfiles = Get-ChildItem -file "C:\folder1"  | Group-Object -Property length
foreach($filegroup in $allfiles)
{
    if ($filegroup.Count -ne 1)
    {
        foreach ($file in $filegroup.Group)
        {
            move $file.fullname "C:\files_compared"
        }
    }
}

Thanks.

Upvotes: 1

Views: 728

Answers (2)

mklement0
mklement0

Reputation: 437197

A (nested) pipeline solution:

Get-ChildItem -file "C:\folder1" | Group-Object -Property length | ForEach-Object {
  $_.Group | Select-Object -Skip 1 | Move-Item -Destination "C:\files_compared"
}
  • $_.Group is the collection of all files that make up a given group (files of the same size).

  • Select-Object -Skip 1 skips the first file in the collection (i.e., leaves it in place) and moves all others - if any - to the destination folder.

    • This approach obviates the need to distinguish between 1-file groups and others (the $filegroup.Count -ne 1 conditional in your code), because for 1-file groups the inner pipeline will simply be a no-op (skipping the first object leaves no objects to pass to Move-Item).

Upvotes: 2

EBGreen
EBGreen

Reputation: 37720

Untested but try this:

$allfiles = Get-ChildItem -file "C:\folder1"  | Group-Object -Property length
foreach($filegroup in $allfiles)
{
    if ($filegroup.Count -ne 1)
    {
        $fileGroup.Group[1..($fileGroup.Count-1)] | move -Destination 'C:\Files_compared'
    }
}

Upvotes: 1

Related Questions