我遇到了與本文中討論的幾乎相同的問題:
從一個目錄複製 100 個新文件,並將每個文件替換為其當前位置的舊文件
我的一個目錄中有 1000 個影片檔。這些是新視頻,需要替換位於許多子目錄中的舊視頻。它們的基本名稱匹配,但擴展名不匹配。在“舊”資料夾中,我的許多子目錄中都有“.MPG”文件,而在“新”資料夾中,我的一個目錄中有“.mp4”文件。在這兩個文件中,我都有具有相同基本名稱的視訊檔案。我怎麼能這麼做呢?
我在 PowerShell 中寫的內容(在 oldfolder 中有 300 個不同的子目錄):
$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]."
}
}
然後我運行了程式碼,錯誤訊息是:
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.
這是因為檔案副檔名不匹配,即使基本名稱匹配,所以我的問題是:我必須在第一個代碼中更改什麼,以便 PowerShell 不關心檔案副檔名?
提前致謝。
答案1
這應該可以解決問題
$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)
}
}
更改副本以移動和添加舊文件的刪除很容易,但我在您的程式碼中看到了 neitehr 。
答案2
視窗 10 64 位元。電源外殼 5.1
基於$_.basename
Look through every "C:\oldfolder"
for行動檔案.mpg
。如果為 true,且$mp4base
等於$mpgbase
,則將 item 移到$mp4
,$mpgdir
然後刪除 item$mpg
並循環,直到沒有$mpg
。為了進行測試,請清理桌面。桌面上不應有名為mp4
或 的目錄。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." }
#