Ich habe fast das gleiche Problem, das in diesem Artikel besprochen wurde:
Ich habe 1000 Videodateien in einem Verzeichnis. Dies sind neue Videos, die alte Videos ersetzen müssen, die sich in vielen Unterverzeichnissen befinden. Ihre Basisnamen stimmen überein, ihre Erweiterungen jedoch nicht. Im Ordner „alt“ habe ich „.MPG“-Dateien in vielen Unterverzeichnissen und im Ordner „neu“ habe ich „.mp4“-Dateien in einem Verzeichnis. In beiden habe ich Videodateien mit demselben Basisnamen. Wie kann ich das machen?
Was ich bei PowerShell geschrieben habe (im oldfolder gibt es 300 verschiedene Unterverzeichnisse):
$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]."
}
}
Dann habe ich den Code ausgeführt und die Fehlermeldung lautet:
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.
Dies liegt daran, dass die Dateierweiterung nicht übereinstimmt, obwohl der Basisname übereinstimmt. Meine Frage lautet daher: Was muss ich im ersten Code ändern, damit PowerShell die Dateierweiterung nicht beachtet?
Dank im Voraus.
Antwort1
Das sollte funktionieren
$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 ist recht einfach, das Kopieren in Verschieben und Löschen alter Dateien zu ändern, aber in Ihrem Code habe ich nichts davon gesehen.
Antwort2
Windows 10 64-Bit. PowerShell 5.1
Verschiebe Dateien basierend auf . $_.basename
Durchsuche alle "C:\oldfolder"
nach .mpg
. Wenn wahr und $mp4base
gleich $mpgbase
, verschiebe Element $mp4
nach $mpgdir
, entferne Element $mpg
und führe eine Schleife aus, bis keine mehr vorhanden sind $mpg
.Leeren Sie zum Testen Ihren Desktop. Auf Ihrem Desktop sollten sich keine Verzeichnisse mit dem Namen mp4
oder befinden.mpg
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." }
#