Created
November 30, 2012 14:01
-
-
Save ebibibi/4175880 to your computer and use it in GitHub Desktop.
デジカメ、スマートフォンなどで撮影した画像、動画ファイルをリネーム後月ごとのフォルダに移動するスクリプト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#-------------------------------------------------------------------------------------------------- | |
# デジカメ、スマートフォンなどで撮影した画像、動画ファイルをリネーム後月ごとのフォルダに移動するスクリプトです。 | |
# 以下のようにリネームします。exif情報があればそれを使って。無ければファイルの作成日時を使います。 | |
# yyyy.mm.dd-hh.mm.ss + オリジナルの拡張子 | |
# リネーム後、指定されたフォルダ内にyyyymmフォルダを作成し、その中に移動します。 | |
# 移動先に同一名称のファイルがあり、同一内容(MD5ハッシュで判断)であれば移動元ファイルを削除します。 | |
# | |
# -SourceDir 移動元ディレクトリを入力します。再帰的にサブディレクトリも対象になります。 | |
# -DestinationDir 移動先ディレクトリを入力します。このディレクトリの下に月ごとのディレクトリが作成され、そこに移動されます。 | |
# -$Filter 対象とするファイルをフィルタで指定します。Get-ChildItemのFilterパラメータにそのまま渡されます。 | |
# | |
# 使用例: | |
# powershell.exe rename_pictures.ps1 -SourceDir c:\source -DestinationDir c:\pictures -Filter *.jpg | |
# | |
# http://ebi.dyndns.biz/ | |
#-------------------------------------------------------------------------------------------------- | |
Param( | |
[string]$SourceDir, | |
[string]$DestinationDir, | |
[string]$Filter | |
) | |
function Format-String($string) | |
{ | |
if($string.length -eq 2) | |
{ | |
return $string | |
} | |
return "0" + $string | |
} | |
function Get-FileDate($file_path) | |
{ | |
try | |
{ | |
[Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null | |
$img = $null | |
$img = New-Object Drawing.Bitmap($file_path) | |
$date = ($img.PropertyItems | Where-Object{$_.Id -eq 306}).value | |
$date = [Text.Encoding]::ASCII.GetString($date).Replace(":",".").Replace(" ", "-") | |
$date = $date.Substring(0, $date.Length -1) | |
$img.Dispose() | |
$img = $null | |
} | |
catch | |
{ | |
Write-Debug "exif情報が取得できなかったため生成日時で処理します。" | |
if (!($img -eq $null)) | |
{ | |
$img.Dispose() | |
$img = $null | |
} | |
#exif情報が取得できなかった場合 | |
$file_info = Get-ItemProperty $file_path | |
$creation_time = $file_info.CreationTime | |
$date = $creation_time.Year.ToString() + "."+ (Format-String $creation_time.Month.ToString()) + "." + (Format-String $creation_time.Day.ToString()) + "-" + (Format-String $creation_time.Hour.ToString()) + "." + (Format-String $creation_time.Minute.ToString()) + "." + (Format-String $creation_time.Second.ToString()) | |
} | |
Write-Debug "日時 : $date" | |
$date | |
} | |
function Get-NewFilename($file_path) | |
{ | |
$ext = [System.IO.Path]::GetExtension($file_path) | |
$date = Get-FileDate $file_path | |
$newname = $date.Replace(":",".").Replace(" ", "-") | |
$newname = $newname + $ext | |
$newname | |
} | |
function Get-Year($file_path) | |
{ | |
$date = Get-FileDate $file_path | |
$date.Substring(0, 4) | |
} | |
function get_month($file_path) | |
{ | |
$date = Get-FileDate $file_path | |
$date.Substring(5, 2) | |
} | |
function Rename-Picture($file_path) | |
{ | |
$new_filename = Get-NewFilename $file_path | |
Write-Host ("rename from: " + $file_path) | |
Write-Host (" to : " + $new_filename) | |
if([System.IO.Path]::GetFileName($file_path) -eq $new_filename) | |
{ | |
Write-Host "既にリネームされています。" | |
} else { | |
if(Test-Path (Join-Path ([System.IO.Path]::GetDirectoryName($file_path)) -ChildPath $new_filename)) | |
{ | |
Write-Host "リネーム後のファイル名が既に存在しています。" | |
} else { | |
Rename-Item -Path $file_path -NewName $new_filename | |
} | |
} | |
$new_filename | |
} | |
function Get-MD5Hash($file) | |
{ | |
$stream = New-Object IO.StreamReader $file | |
$md5 = [System.Security.Cryptography.MD5]::Create() | |
$hash = $md5.ComputeHash($stream.BaseStream) | |
$result = [System.BitConverter]::ToString($hash).ToLower().Replace("-","") | |
Write-Debug "MD5 for $file : $result" | |
$result | |
} | |
function IsSame-MD5Hash($file1, $file2) | |
{ | |
$hash1 = Get-MD5Hash $file1 | |
$hash2 = Get-MD5Hash $file2 | |
return ($hash1 -eq $hash2) | |
} | |
function RenameAndMove-Files($files, $DestinationDir) | |
{ | |
$files | ForEach-Object { | |
$childdir = (Get-Year $_.fullname) + (get_month $_.fullname) + "\" | |
Write-Debug "childdir : $childdir" | |
$destination = Join-Path $DestinationDir -ChildPath $childdir | |
Write-Debug "destination : $destination" | |
if((Test-Path $destination) -eq $false) | |
{ | |
Write-Host ("make dir:" + $destination) | |
mkdir $destination -Force | |
} | |
$new_filename = Rename-Picture($_.fullname) | |
$new_fullpath = Join-Path ($_.directory.fullname) -ChildPath $new_filename | |
Write-Host ("move from:" + $new_fullpath) | |
Write-Host (" to :" + $destination) | |
if(Test-Path (Join-Path $destination -ChildPath $new_filename)) | |
{ | |
Write-Host "既に移動先に同一ファイルが存在します。ハッシュ値を比較します。" | |
$result = IsSame-MD5Hash (Join-Path $destination -ChildPath $new_filename) $new_fullpath | |
if ($result) | |
{ | |
Write-Host "同一ファイルだったため、移動元ファイルを削除します。" | |
Remove-Item -Path $new_fullpath -Force | |
} else { | |
Write-Host "移動先と同一ファイルではなかったため、ファイルは削除しません。" | |
} | |
} | |
else | |
{ | |
Move-Item -path $new_fullpath -Destination (Join-Path $destination -ChildPath $new_filename) | |
} | |
} | |
} | |
#メイン処理 | |
if (($SourceDir -eq "") -or ($DestinaionDir -eq "") -or ($Filter -eq "")) | |
{ | |
Write-Host "-SourceDir, -DestinationDir, -Filter オプションは必須です。" | |
return | |
} | |
$files = Get-ChildItem -Path $SourceDir -Recurse -Filter $Filter | |
if($files -eq $null) | |
{ | |
Write-Host "対象ファイルはありませんでした。" | |
} else { | |
RenameAndMove-Files $files $DestinationDir | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment