【PowerShell】内容が重複したファイルを削除する

 自動でファイルを生成するスクリプトを動かした時、しばしば内容が重複する無駄なファイルを作ってしまう場合があります。そういった際などに使える、内容が重複したファイルを削除するスクリプトを紹介します。実際のコードが次です。

param(
    # 引数でディレクトリパスが渡されない場合はスクリプトファイル自身のディレクトリを取得
    [string]$directoryPath = $(Split-Path -Parent $MyInvocation.MyCommand.Definition)
)

# ディレクトリ配下の全ファイルを再帰的に読み込む
$files = Get-ChildItem -Path $directoryPath -Recurse -File

# ハッシュテーブルを用いる。ここにファイルの内容をハッシュ化して格納する
$hashTable = @{}
foreach ($file in $files) {
    # ファイルの内容についてのハッシュ値を取得
    $hash = Get-FileHash $file.FullName -Algorithm SHA256
    # 得られたハッシュ値がハッシュテーブルのキーに既に存在するかチェック
    if ($hashTable.ContainsKey($hash.Hash)) {
        # ハッシュ値が既にに存在する場合、ゴミ箱に移動
        $existingFile = $hashTable[$hash.Hash]
        [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($file.FullName, 'OnlyErrorDialogs', 'SendToRecycleBin')
        Write-Host $file.FullName
    } else {
        # 存在しない場合、ハッシュテーブルにハッシュ値とファイルのパスのペアを追加
        $hashTable[$hash.Hash] = $file.FullName
    }
}

 使い方は削除したいファイル群のディレクトリにこのファイル(仮にremove.ps1とします)を置いてremove.ps1とするかremove.ps1 [削除したいファイル群のあるディレクトリのフルパス]とするかです。

 コードはファイルの内容そのものを保持するのではなくハッシュ値にし、それのテーブルを使うのがポイントです。ファイルの内容をそのまま保持するとメモリに優しくなく、全く保持せず毎回すべてのファイル内容を読むと実行速度が遅くなってしまいます。

 PoweShell備え付けのRemove-Itemを使っているのではなく[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFileを使っている理由は、完全な削除ではなくゴミ箱送りにしたいからです。確認メッセージ無しの手軽な削除かつ巻き戻しが効くという点でゴミ箱送りは便利な方法です。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG