Skip to content

Instantly share code, notes, and snippets.

@ebibibi
Created November 30, 2012 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ebibibi/4175880 to your computer and use it in GitHub Desktop.
Save ebibibi/4175880 to your computer and use it in GitHub Desktop.
デジカメ、スマートフォンなどで撮影した画像、動画ファイルをリネーム後月ごとのフォルダに移動するスクリプト
#--------------------------------------------------------------------------------------------------
# デジカメ、スマートフォンなどで撮影した画像、動画ファイルをリネーム後月ごとのフォルダに移動するスクリプトです。
# 以下のようにリネームします。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