私はこの記事で議論されたのとほぼ同じ問題を抱えています:
1 つのディレクトリから 100 個の新しいファイルをコピーし、各ファイルを現在の場所にある古いファイルと置き換えます。
1 つのディレクトリに 1000 個のビデオ ファイルがあります。これらは、多数のサブ ディレクトリにある古いビデオを置き換える必要がある新しいビデオです。ベース名は一致していますが、拡張子が一致していません。「古い」フォルダーには多数のサブディレクトリにある「.MPG」ファイルがあり、「新しい」フォルダーには 1 つのディレクトリに「.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
に基づいてファイルを移動します。すべてのfor$_.basename
を調べます。true かつ と等しい場合、項目を に移動し、項目を削除して、 がなくなるまでループします。"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." }
#