¿Cómo reemplazar archivos cuyas extensiones no coinciden?

¿Cómo reemplazar archivos cuyas extensiones no coinciden?

Tengo casi el mismo problema que se discutió en este artículo:

copie 100 archivos nuevos de un directorio y reemplace cada archivo con los archivos antiguos en su ubicación actual

Tengo 1000 archivos de video en un directorio. Estos son videos nuevos que deben reemplazar los videos antiguos que se encuentran en muchos subdirectorios. Sus nombres base coinciden pero sus extensiones no. En la carpeta "antigua" tengo archivos ".MPG" ubicados en muchos subdirectorios y en la "nueva" tengo archivos ".mp4" en un directorio. En ambos tengo archivos de video con el mismo nombre base. ¿Cómo podría hacer eso?

Lo que escribí en PowerShell (en la carpeta antigua hay 300 subdirectorios diferentes):

$newFiles = "C:\newfolder"
$oldFiles = "C:\oldfolder"

Get-ChildItem $newFiles | ForEach-Object {

    $currentFile = $_

    $oldFileLocation = Get-ChildItem -Recurse $oldFiles | Where-Object { $_ -Match "$currentFile"} | Select-Object -ExpandProperty DirectoryName

    if($oldFileLocation) {   # if this variable is not null, we've found original file location
        Write-Host "found file [$currentFile] in location: [$oldFileLocation]. overwriting the original."
        Copy-Item -Path $newFiles\$currentFile -Destination $oldFileLocation -Force
    }
    else {
        Write-Warning "could not find file [$currentFile] in location [$oldFiles]."
    }

}

Luego ejecuté el código y el mensaje de error es:

WARNING: could not find file [M2U00386.mp4] in location [C:\oldfolder].
WARNING: could not find file [M2U00387.mp4] in location [C:\oldfolder].
WARNING: could not find file [M2U00388.mp4] in location [C:\oldfolder].
WARNING: could not find file [M2U00389.mp4] in location [C:\oldfolder].
.
.
. # and so on because it would find them if the new files were M2U00386.MPG not .mp4.

Esto se produce porque la extensión del archivo no coincide aunque el nombre base sí, así que mi pregunta es: ¿qué tengo que cambiar en el primer código para que a PowerShell no le importe la extensión del archivo?

Gracias de antemano.

Respuesta1

Esto debería funcionar

$newFiles = 'C:\newfolder'
$oldFiles =  'C:\oldfolder'

$oldHash = @{}
Get-ChildItem $oldFIles -File -Recurse | ForEach{
    $oldHash.Add($_.BaseName, $_.DirectoryName)
}

Get-ChildItem $newFiles | ForEach{
    If ($_.BaseName -in $oldHash.Keys) {
        Copy-Item $_.FullName  $oldHash[$_.BaseName]
    } Else {
        echo ('No match found for "{0}".' -f $_.Name)
    }
}

Es bastante fácil cambiar la copia para mover y agregar la eliminación de archivos antiguos, pero no vi nada en su código.

Respuesta2

Ventana 10 de 64 bits. PowerShell 5.1

Mueva archivos basándose en $_.basenameBuscar en cada "C:\oldfolder"for .mpg. Si es verdadero y $mp4basees igual a $mpgbase, mueva el elemento $mp4a $mpgdir, elimine el elemento $mpgy realice un bucle hasta que no haya ningún $mpg.Para realizar pruebas, limpie su escritorio. No debería haber directorios con nombre mp4ni mpgen su escritorio.

pushd $env:USERPROFILE\Desktop;ni -itemtype directory "mp4", "mpg\mpg2">$null;foreach($i in 1..20){ni -itemtype file "mp4\$i.mp4">$null };foreach($i in 1..10){ni -itemtype file "mpg\$i.mpg">$null };foreach($i in 11..20){ni -itemtype file "mpg\mpg2\$i.mpg">$null };popd;
$Files = @(Get-ChildItem .\mpg\*.mpg -recurse)
if (!($Files.length -eq 0)) {
Get-ChildItem mp4 | ForEach-Object { 
    $mp4= $_.fullname
    $mp4base= $_.basename
Get-ChildItem mpg -recurse | ForEach-Object {
    $mpg = $_.fullname
    $mpgbase= $_.basename
    $mpgdir= $_.directoryname
    if ($mp4base -eq $mpgbase) {
    move-item $mp4 $mpgdir
    remove-item $mpg
    }
}} 
explorer .\mpg;cls 
Read-Host "    
Press enter key to delete all test files"
ri (".\mpg", ".\mp4") -recurse -force 
#
popd 
#    
} else {write-host "   No .mpg to process." }
# 

información relacionada