画像ファイルを名前の日付で分類(DateTime.TryParseExact の使い方メモ)
が結構便利そうだったので使い方の確認がてらPowerShellでタイトルの処理を作ってみた。
対象のファイル群
Dropboxの自動アップロードによってスマホからPCに同期された画像ファイルに対して処理を行う。
画像ファイルの名前は自動で2018-03-23 12.34.56.jpg
といった形式となるため、その名前を日付に変換して分類を行う。
コード
<# .Synopsis Dropboxでアップロードされた画像ファイルを日付で分類する yyMMのフォルダを作成して、その中に移動する #> [string]$rootPath = # カレントディレクトリ以下のファイルを対象にする場合 $PWD.ProviderPath # PS1として保存して、その保存先フォルダ内を対象にする場合 #[IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Definition) # Dropboxで自動アップロードされたファイルは以下のような名前になる # e.g. 2018年3月23日12時34分56秒に撮影した画像の場合 # 2018-03-23 12.34.56.jpg [string]$dateFormat = 'yyyy-MM-dd HH.mm.ss' # DateTime.TryParseExact の引数指定が面倒だったため、スクリプトブロックに格納 [scriptblock]$tryParse = { param([string]$dateString, [ref]$outDate) return [datetime]::TryParseExact( $dateString, $dateFormat, [Globalization.DateTimeFormatInfo]::CurrentInfo, [System.Globalization.DateTimeStyles]::None, $outDate ) } # パースした結果受け取り用変数 [datetime]$parsedDate = [datetime]::MinValue # $rootPath 内のファイルに対して操作 Get-ChildItem -LiteralPath $rootPath | # 名前を日付に変換できるものだけにフィルター ?{$tryParse.Invoke( # $_ には [System.IO.FileSystemInfo] が入るはず [IO.Path]::GetFileNameWithoutExtension($_.Name), [ref]$parsedDate) } | # 取得した日付を書式設定した値でグループ化(PowerShellのパイプラインの動作上、$parsedDateはちゃんと反映される) Group-Object -Property {$parsedDate.ToString('yyMM')} | # 各グループに対して処理 %{ # 出力先のフォルダ作成 # [IO.Directory]::CreateDirectory は冪等性のある処理っぽいのですでに存在していてもOK [string]$destDir = [IO.Path]::Combine($rootPath, $_.Name) [IO.Directory]::CreateDirectory($destDir) > $null # 各ファイルを移動 $_.Group | %{ [string]$moveToPath = [IO.Path]::Combine($destDir,$_.Name) Write-Host ('{0} => {1}' -f $_.Name, [IO.Path]::GetFileName($destDir)) $_.MoveTo($moveToPath) } }