ドラレコで録画した映像ですが。ファイル数が数千~数万個あって、手がつけられません。
PowerShellを使って、こちらを自動で整頓したいと思います。
ファイル名の日付を判別して、自動で日付のフォルダに移動してみました。
フォルダ名に曜日と祝日・休日もいれると、このような感じです。これなら、平日に運転した記録か、なにか休日に遊びに行った記録か、すぐ判別することが可能です。
方法を記録しておこうと思います。
目次
PowerShellでファイルを日付+曜日+祝日・休日のフォルダに自動移動する手順
PowerShellの実行はISEを使用
PowerShellのスクリプトの実行は、Windows PowerShell ISEを使用しました。
OSはWindows 10ですが、標準でOSに付属しているものです。Windows 11でも付属していると思います。このような感じで、画面の上半分にスクリプトを貼って、▶ボタンで実行しました。
ではそのスクリプトについて。
PowerShellのフォルダ選択ダイアログ表示について
ファイルを整頓する対象のフォルダは、「フォルダーの参照」ダイアログボックスで選択できます。
該当のコードは、このあとご紹介するスクリプトに組み込まれていますが、詳細を知りたい場合はこちらになります。
ファイル名から日付の取り出しについて
ファイル名から日付を取り出す方法の詳細はこちらになります。こちらも後で出てくるクラスに組み込み済みです。
日付から曜日と祝日・休日名称の判別について
ファイルを入れるフォルダですが、日付+曜日+祝日・休日の場合はその名称を付けました。
この記事では、$env:TEMPフォルダに祝日・休日のCSVファイルをダウンロードします。ダウンロード済みかどうか判定しているため、2回目以降の実行は、インターネットの接続は行われません。
ファイル名の日付からフォルダに整頓するPowerShellスクリプト
以上の内容を組み合わせて、クラスを作ってみました。
# Powershell ちょっとしたファイル操作クラス
# © 2024 denor.jp
class DenorFileUtility {
[System.Object[]] $syukujitsuCsv # 祝日・休日CSV
# コンストラクタ
DenorFileUtility() {
$this.ImportSyukujitsuCsv() # 祝日・休日CSVファイル読み込み
}
# 祝日・休日CSVファイルを変数に読み込みます
[void] ImportSyukujitsuCsv() {
# ダウンロード済みなら終了
if($this.syukujitsuCsv -ne $null) {
return
}
# CSVファイルパス 環境変数TEMP
$outfile = $env:TEMP + "\syukujitsu.csv"
if ( -not (Test-Path -Path $outfile)) {
try {
# ファイルがなければダウンロード
Invoke-WebRequest `
-URI https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv `
-OutFile $outfile
} catch {
Write-Host "CSVファイルをダウンロードできませんでした。"
Write-Host $_
exit
}
} else {
write-verbose "CSVファイルはダウンロード済みです"
}
# メンバ変数へCSV読み込み
$this.syukujitsuCsv = Import-Csv $outfile -Encoding Default
}
# 祝日・休日を検索します
[string] GetSyukujitsu([datetime]$date) {
$syukujitsu = ($this.syukujitsuCsv | Where-Object "国民の祝日・休日月日" -Match $date.ToString("yyyy/M/d"))."国民の祝日・休日名称"
return $syukujitsu
}
#ドライブレコーダー録画ファイル名から日付を取り出して返します
static [Array] GetDateByFileName([string]$filename) {
if($filename -Match '^(?<year>\d{4})_(?<month>\d{2})(?<day>\d{2})_(?<hour>\d{2})(?<minute>\d{2})(?<sec>\d{2})' -ne $true) {
return $null
}
return @{
Year = $Matches.year
Month = $Matches.Month
Day = $Matches.day
Hour = $Matches.hour
Minute = $Matches.minute
Sec = $Matches.sec
}
}
# フォルダ選択ダイアログを表示します
static [string] SelectFolder() {
return [DenorFileUtility]::SelectFolder("")
}
# フォルダ選択ダイアログ表示
static [string] SelectFolder([string]$InitialFolder) {
Add-Type -AssemblyName System.windows.forms
$dialog = New-Object -TypeName System.Windows.Forms.FolderBrowserDialog
$dialog.rootfolder = "MyComputer"
$dialog.SelectedPath = $InitialFolder
if($dialog.ShowDialog() -ne "OK") {
$selected = $null
} else {
$selected = $dialog.SelectedPath
}
Remove-Variable -Name dialog
return $selected
}
# 日付+曜日+祝日休日名のフォルダ名を生成します
[string] GetDateFolderName([System.Object[]]$filedate) {
# 日付オブジェクト作成
$date = Get-Date -year $filedate.year -month $filedate.month -day $filedate.day
$foldername = $filedate.year + $filedate.month + $filedate.day + $date.ToString("ddd")
# 祝日・休日名取得
$syukujitsu = $this.GetSyukujitsu($date)
if ($syukujitsu -ne "" ) {
$foldername = $foldername + "_" + $syukujitsu
}
Remove-Variable -Name syukujitsu
Remove-Variable -Name date
return $foldername
}
# 選択したフォルダにあるファイル名から日付を取り出し、日付のフォルダにファイルを移動します
[void] MoveFilesToDateFolder() {
# フォルダ選択
$folder = [DenorFileUtility]::SelectFolder()
if($folder -eq "") {
return
}
# フォルダ移動
Push-Location $folder
# ファイル一覧取得
$files = Get-ChildItem -File
foreach($file in $files) {
#[System.IO.FileInfo] $file
# 日付取り出し
$filedate = [DenorFileUtility]::GetDateByFileName($file.Name)
if($filedate -eq $null) { continue }
"対象のファイル名: " + $file.Name | Write-Verbose
# 日付からフォルダ名作成
$foldername = $this.GetDateFolderName($filedate)
$folderpath = ".\"+ $foldername
if ( -not (Test-Path -Path $folderpath)) {
"ディレクトリを作成します: " + $foldername | Write-Verbose
New-Item -Path ".\" -Name $foldername -ItemType "directory"
}
# ファイルを移動
"ファイルを移動します: " + $folderpath | Write-Verbose
$file.MoveTo($folder + "\" + $folderpath + "\" + $file.Name)
}
Pop-Location
Remove-Variable -Name files
Remove-Variable -Name folder
}
}
# 詳細表示モード有効
$VerbosePreferenceDefault = $VerbosePreference
$VerbosePreference = "continue"
# インスタンス生成
$util = [DenorFileUtility]::new()
# ファイルを日付のフォルダに移動
$util.MoveFilesToDateFolder()
# インスタンス削除
Remove-Variable -Name util
# © 2024 denor.jp
こちらをWindows PowerShell ISEに貼り付けて実行すれば、前述のフォルダ選択ダイアログが表示されます。
クラスで実装した理由は、モジュールとして再利用できること・変数の管理が楽な理由からです。(クラスならnewする変数が1つだけでOK
モジュールの実装方法は、追々別の記事にて。
便利ですねPowerShell。
Windowsに付属しているということで、なにかコンパイラやランタイムのインストールは不要で、ISEを起動するだけで使用できてしまいます。
編集・実行だけではなく、F5キーでデバッグ実行までできるため、バグの修正も簡単にできます。
連休の時期のため、お車で出かけることもあるかと思います。
ドライブレコーダーの映像が溜まって、手が付けらず、放置しているのでしたら。(私だ
日付ごとにフォルダ分けするだけで、不要な映像、大切な映像の判断が、ずいぶん楽になると思います。
どんなWindows PCでも実行できますので、よろしければお試し下さい。