有馬総一郎のブログ

(彼氏の事情)

2021年07月23日 19:45:16 JST - 3 minute read - PowerShell

音楽フォルダ配下の空フォルダをPowerShellで一括削除する。

音楽フォルダ配下の空フォルダを削除したいと思って調べてみた。

空フォルダを一括削除するPowerShellスクリプト | 有限工房が見付かったので試してみた。こちらは除外ファイルを指定できるのが素晴しい。

すると、空でないフォルダまでが対象となってしまう…

#削除対象フォルダ(ここから下の空フォルダを削除する)
$TARGET_ROOT = "E:\Share\LocalSync\壁紙"

#除外ファイル(これらファイルは存在しないものとみなす)
$EXCLUDES = @("Thumbs.db", ".nomedia", "_filemany.simDB")


Write-Host "`n----- 開始 -----" -ForegroundColor Green

#並びを逆にする = フォルダの深い順に並べ替える
$targets = Get-ChildItem -Path $TARGET_ROOT -Directory -Recurse | Sort-Object -Descending

foreach ($target in $targets) {
    #除外ファイル以外のファイル数が0なら削除
    $items = Get-ChildItem -Path $target -Exclude $EXCLUDES -Recurse
    if ($items.Count -eq 0) {
        Write-Host "Delete: $target"
        # Remove-Item $target -Recurse -Force     #Forceで隠しファイルもろとも削除
    }
}

Write-Host "----- 終了 -----" -ForegroundColor Green

どうも削除ディクレトリをしてする$targeがフルパスでないために、うまくいってないようだ。

上記のスクリプトを以下のように書き換えた。

#削除対象フォルダ(ここから下の空フォルダを削除する)
$TARGET_ROOT = "C:\My Music"

#除外ファイル(これらファイルは存在しないものとみなす)
$EXCLUDES = @("Thumbs.db", ".nomedia", "_filemany.simDB", "folder.jpg", "folder.png", "cover.jpg", "cover.png", "artist.jpg", "artist.png")


Write-Host "`n----- 開始 -----" -ForegroundColor Green

#並びを逆にする = フォルダの深い順に並べ替える
$targets = Get-ChildItem -Path $TARGET_ROOT -Directory -Recurse | Sort-Object -Descending

foreach ($target in $targets) {
    #除外ファイル以外のファイル数が0なら削除
    $items = Get-ChildItem -LiteralPath $target.FullName -Exclude $EXCLUDES -Recurse
    if ($items.Count -eq 0) {
        Write-Host "Delete: $($target.FullName)"
        # Remove-Item $target -Recurse -Force     #Forceで隠しファイルもろとも削除
    }
}

Write-Host "----- 終了 -----" -ForegroundColor Green

$TARGET_ROOTは当然変えるとして、$EXCLUDESは画像ファイルだけあるフォルダも存在する可能性があるので、"folder.jpg", "folder.png", "cover.jpg", "cover.png", "artist.jpg", "artist.png"を追加。

肝心のGet-ChildItemの部分は、まず-Pathはそのままだと、[とか記号を含むパスだと困るので、-LiteralPathと変更。

そして、$target$target.FullNameと変更してフルパスになるようにした。

そして、端末出力として"Delete: $target""Delete: $($target.FullName)"として、ここもフルパスで出力されるようにした。

意外と文字列の中で変数を展開方法で迷った。変数そのままなら$targetでいいけど、スペースを含まない場合、どこまでが変数名か分からないので${target}とする必要がある。更に、変数のプロパティやらメソッドを実行する場合は$($target.プロパティやらメソッド)とする必要がある。

結果としては問題なかった。

----- 開始 -----
Delete: C:\My Music\Playlists\Media Go
Delete: C:\My Music\iTunes\iTunes Media\iTunesに自動的に追加
Delete: C:\My Music\iTunes\Album Artwork\Generated
Delete: C:\My Music\iTunes\Album Artwork\Download
Delete: C:\My Music\iTunes\Album Artwork\Custom
Delete: C:\My Music\iTunes\Album Artwork\Cache\1BF1E8A532380685\12\15\15
Delete: C:\My Music\iTunes\Album Artwork\Cloud Purchases\1BF1E8A532380685\05\12\14
Delete: C:\My Music\iTunes\Album Artwork\Cache\1BF1E8A532380685\09\02\12
Delete: C:\My Music\iTunes\Album Artwork\Cache\1BF1E8A532380685\02\13\11
Delete: C:\My Music\iTunes\Album Artwork\Cache\1BF1E8A532380685\06\11\08
Delete: C:\My Music\iTunes\Album Artwork\Cache\1BF1E8A532380685\15\15\05
Delete: C:\My Music\iTunes\Album Artwork\Cache\1BF1E8A532380685\07\03\04
----- 終了 -----