質問: あるフォルダに保存されている大量(10万件を超える)の画像ファイルを整理したいです。 出来ればバッチファイルで組めればと考えています。 =フォルダ構成= 「フォルダA」「フォルダB」「フォルダC」...(30件ほどのフォルダがあります) それぞれのフォルダの直下に「test20180903083503.jpg」などの画像ファイルが存在しています。 ファイル数は数千~数十万件です。 =画像ファイル形式= 例:test20180903083503.jpg 先頭の「test」、拡張子の「.jpg」は固定です。 ご覧の通りtestの後は日付となっているためファイル名称は固定長です。 =やりたいこと= 1. 「フォルダA」など各フォルダの中に存在している画像ファイルを、ファイル名称から自動で作成したサブフォルダに格納していきたいです。 2. サブフォルダは「フォルダA」⇒「yyyy」⇒「0m」⇒「0d」という形で、例題の「test20180903083503.jpg」であれば「フォルダA」⇒「2018」⇒「09」⇒「03」に格納したいと考えています。 3. 定期的に発生する作業のため、「フォルダA」の直下に存在する画像ファイルからサブフォルダの作成と画像ファイルの移動を自動化したいです。 これを「フォルダA」「フォルダB」「フォルダC」...それぞれで行いたいと考えています。 =備考= * 「フォルダA」「フォルダB」「フォルダC」が格納されている親ディレクトリで実行できれば大変嬉しいですが、フォルダ毎に手動実行で問題ありません。 * CSV形式ですが、「フォルダA」などのフォルダ名となる文字列が行ごとに格納されたテキストファイルは存在しています。 * もちろん、前項のCSVファイルを使用する必要はありません。 =試行= 以下の内容で試してみましたが目的の動作が出来ませんでした。 ``` @Echo off rem カレントディレクトリを移動 cd /d %~dp0 rem 遅延環境変数に対応 setlocal ENABLEDELAYEDEXPANSION rem サーバIPアドレス設定 set srv_IP=192.168.1.105 rem 設定ファイルダウンロード元取得 for /f "tokens=1,* skip=1 delims==" %%a IN (\\%srv_IP%\設定ファイル.ini) do ( set %%a=%%b ) rem フォルダー名称をCSVファイルから取得 for /f "delims=, tokens=5" %%a in (%FolderName%) do ( rem 移動元フォルダに存在している画像ファイル名称を取得 for /r %FolderPath%\%%a %%i in (test*.jpg) do ( set filename=%%~ni rem 画像ファイル移動処理 robocopy %FolderPath%\%%a %FolderPath%\%%a\!filename:~4,4!\!filename:~8,2!\!filename:~10,2! /s /mov /r:1 /w:1 ) ) ``` =動作結果= 以上の内容を実施すると、robocopyコマンドの部分で最初に読み込んだ「test20180903083503.jpg」で作成した「フォルダA」⇒「2018」⇒「09」⇒「13」へ「test20180903083503.jpg」が移動するのは良いものの、続く「test2018090**4**120000.jpg」も同様のフォルダに移動してしまいます。 目論見としては「test2018090**4**120000.jpg」は「2018」⇒「09」⇒「04」に移動して欲しいです。 少しVBの想像があったのですが、バッチファイルでは変数が更新されることなくforの中のrobocopyコマンドで移動元から移動先への処理が最後まで進んでしまうとのことでした。 上記、どうか教えて頂けますでしょうか?
回答: robocopyの使い方の問題と思われます。 robocopyの第三パラメーターにファイルを指定していないので、フォルダ内を丸ごと移動してしまっているような気がします。 あと/sオプションも不要かと。少なくとも下記サンプルではあるとダメでした。 下記はカレントフォルダにあるファイルを対象に行った例です。 ``` @Echo off setlocal ENABLEDELAYEDEXPANSION rem フォルダー名称をCSVファイルから取得 for %%i in (test*.jpg) do ( set filename=%%~ni robocopy . .\!filename:~4,4!\!filename:~8,2!\!filename:~10,2! %%i /mov /r:1 /w:1 ) ```