如何使用 Powershell 将具有相同文件名但不同扩展名的文件移动到同一文件夹(包括子目录)

如何使用 Powershell 将具有相同文件名但不同扩展名的文件移动到同一文件夹(包括子目录)

我有很多文件,它们的名字相同,但扩展名不同,位于不同的文件夹中(通常是 .jpg、.crw 和 .xmp)。具有适当元数据的文件已移至各自的文件夹中,但尤其是原始文件仍保留在根文件夹(或上层文件夹)中。

现在的情况:

C:\Source\Pictures\
  FileOne.CRW
  FileTwo.CRW
  FileXXX.CRW
C:\Source\Pictures\Metadata\
  FileOne.XMP
  FileOne.JPG
  FileTwo.XMP

我正在寻找:

C:\Source\Pictures\
  FileXXX.CRW
C:\Source\Pictures\Metadata\
  FileOne.XMP
  FileOne.CRW
  FileOne.JPG
  FileTwo.XMP
  FileTwo.CRW

最好将原始文件(.CRW、.CR2)移动到相应的 .xmp/.jpg/.tif 文件所在的文件夹中,但如果将所有相应的文件移动到一个文件夹中也足够了。

我尝试了以下方法,但它只适用于两种文件类型。它会将所有文件移动到一个目标文件夹。我对此还算满意,但如果它可以处理更多扩展名,并将原始文件移动到 .XMP(或 .JPG/.TIF)文件所在的文件夹,那就更好了。

## INPUT DETAILS
$source_Path = Read-Host -Prompt 'Enter source path'
$dest_Path = Read-Host -Prompt 'Enter destination path'

$ext_GetName = Read-Host -Prompt 'Enter extension name of RAW file (default: ARW)'
if(-not($ext_GetName)){
    $ext_GetName = 'ARW'
}
elseif($ext_GetName.Length -ge 4){
    Write-output "Extension name is not compatible, make sure you are typing the input max of 3 characters only."
    $ext_GetName = Read-Host -Prompt 'Enter extension name of RAW file (default: ARW)'
}


$ext_FindName = Read-Host -Prompt 'Enter extension name of compressed pictures (default: JPG)'
if(-not($ext_FindName)){
    $ext_FindName = 'JPG'
}
elseif($ext_FindName.Length -ge 4){
    Write-output "Extension name is not compatible, make sure you are typing the input max of 3 characters only."
    $ext_FindName = Read-Host -Prompt 'Enter extension name of compressed pictures (default: JPG)'
}



## IF YOU WANT TO USE STATIC DETAILS
## -------------------#

## EXTENSION NAMES
#$ext_GetName = "CR2"
#$ext_FindName = "JPG"
## PATH
#$source_Path = "F:\Pictures\FAMILY, LOVE, FRIENDS, TRAVEL PHOTOS\_Photo Archives\2022-11-28 (AYALA LIGHTS)"
#$dest_Path = "c:\temp\test"
## -------------------#

$ext_GetName_incl = "*."+$ext_GetName
$ext_FindName_incl = "*."+$ext_FindName

$RAWfiles = Get-ChildItem -Path $source_Path -Include $ext_GetName_incl -Recurse -Force -ErrorAction SilentlyContinue

$COMPfiles = Get-ChildItem -Path $source_Path -Include $ext_FindName_incl -Recurse -Force -ErrorAction SilentlyContinue

write-host "Looking for "$ext_GetName" files for chosen "$ext_FindName" files in "$source_Path

##FOR TESTING## Get-ChildItem -Path $source_Path -Include $ext_xxxxx_xxx -Recurse -Force -ErrorAction SilentlyContinue

$counter=0
foreach( $RAWfile in $RAWfiles ) 
{
    foreach( $COMPfile in $COMPfiles ) 
    {   
        if(($RAWfile.BaseName -eq $COMPfile.BaseName)) 
        { 
            write-host Successfully copied $RAWfile.name 
            Move-Item $RAWfile.fullname $dest_Path
            Move-Item $COMPfile.fullname $dest_Path
            $counter++
        }
    }
}

write-host Successfully copied $counter files to $dest_Path
pause

任何帮助,将不胜感激!

答案1

以下是 powershell 中的一个示例:

$src = "C:\Source"
$dst = "C:\Destination"

# get all the files including in subfolders, without including directory names
$files = Get-ChildItem $src -Recurse -File

# group files by name, and only the ones with matches
$grouped = $files | Group-Object -Property BaseName | Where Count -GE 2
foreach ($group in $grouped){

  # copy each group of files to a single folder
  $group.Group.Fullname | Copy-Item -Destination (Join-Path $dst $group.Name)

}

例如,此源文件夹中的文件:

C:\Source\Pictures\RAW\
  FileOne.ARW
  FileTwo.ARW
  FileThree.ARW
C:\Source\Pictures\Compressed\
  FileOne.JPG
  FileTwo.JPG

将被复制到目标位置,例如:

C:\Destination\FileOne\
  FileOne.ARW
  FileOne.JPG
C:\Destination\FileTwo\
  FileTwo.ARW
  FileTwo.JPG

相关内容