我遇到的问题与本文讨论的问题几乎相同:
从一个目录复制 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)
}
}
将复制改为移动以及添加删除旧文件相当容易,但我在您的代码中却看不到。
答案2
Windows 10 64 位。PowerShell 5.1
根据 移动文件$_.basename
查找每一个"C:\oldfolder"
。.mpg
如果为真,且$mp4base
等于$mpgbase
,则将项目移动$mp4
到$mpgdir
,删除项目$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." }
#