この記事では、バッチファイルにドロップした複数のフォルダを新規フォルダへコピーする方法についてご説明します。
なお今回のバッチファイルは、フォルダをコピーする際は指定したファイルサイズでコピー制限するコードに盛り込みます。
指定したファイルサイズでコピー制限する指定をコードに盛り込むことで、フォルダをバッチファイルにドロップした際、バッチファイル実行時にその指定したファイルサイズに該当するファイルのみコピーします。
今回指定するファイルサイズのコピー制限は、指定した容量以上のファイルだけをコピーするか、指定した容量以下のファイルだけをコピーするかのどちらかです。
今回紹介するバッチファイルの処理の大まかな流れは次の通りです。
なお、今回作成する新規フォルダの名前は、「バックアップ_年月日時分秒」(※例:バックアップ_20240109075525)とします。
新規フォルダは、フォルダ名が重複しないよう一意の名前で生成することが狙いです。
今回は、指定した容量以上のファイルだけをコピーするか、指定した容量以下のファイルだけをコピーする条件を指定します。
ちなみに、記事タイトルに「複数のフォルダ」としてはいますが、単一のフォルダにも対応しています。
【動画】(指定した拡張子のファイルを除外して)バッチファイルにドロップした複数のフォルダを新規フォルダへコピーする実際の動き
本題に入る前に、まずは次の動画をご覧ください。
注意
今回紹介するバッチファイルはフォルダをコピーするので、大事なファイルを上書きしてしまったり、フォルダが生成されるなど、パソコン内のディレクトリ環境を変えてしまう場合があります。
バッチファイルを実行する前は、必ずコピー先の指定に十分お気を付けください。
その点を留意して自己責任でお使いいただければ幸いです。
フォルダの例
「C:¥work¥10_勉強¥17_バッチファイル¥0012¥from」配下のフォルダに、「data」「file」「xyz 2023」というフォルダが存在しています。
今回はこの「data」「file」「xyz 2023」の3つのフォルダをバッチファイルにドロップすると、「C:¥work¥10_勉強¥17_バッチファイル¥0012¥to」配下に新規フォルダを作成してその中にドロップしたフォルダをコピーします。
バッチファイルが作成する新規フォルダ(サンプル)は下のとおりです。
新規フォルダには、「バックアップ_年月日時分秒」(※例:バックアップ_20240122095955)の名前が付けられます。
なお、今回のバッチファイルのサンプルでは、サイズが5メガ以上のファイルは除外するよう指定します。
今回はバッチファイルにドロップするフォルダを3つ用意しました。
「data」「file」「xyz 2023」のフォルダには下のファイルとフォルダが格納されています。
①「data」
②「file」
③「xyz 2023」
今回紹介するバッチファイルにフォルダをドロップして実行させると、指定したコピー先に新規フォルダが作成され、その新規フォルダ配下に「data」「file」「xyz 2023」全てフォルダがコピーされます。
コピーされた「data」「file」「xyz 2023」それぞれのフォルダ配下は下のとおりです。
①「data」
②「file」
③「xyz 2023」
各フォルダ配下を見てみると、拡張子が「txt」「csv」のファイルはコピーされず、拡張子が「txt」「csv」以外のファイル全てがコピーされています。
条件にファイルサイズが5メガ以下のファイルのみ、と指定しているので、ファイルサイズが5メガ以下のファイルのみコピーされています。
ちなみに5メガ以下のファイルはを除外するよう指定してバッチファイルにフォルダをドロップした結果は下のとおりです。
①「data」
②「file」
③「xyz 2023」
条件にファイルサイズが5メガ以上のファイルのみと指定しているので、ファイルサイズが5メガ以上のファイルのみコピーされています。
コードの例
@echo off rem コピー先のフォルダを指定する set copyToParent=C:\work\10_勉強\17_バッチファイル\0012\to rem 遅延環境変数展開を有効にする setlocal enabledelayedexpansion rem 現在の年月日時分秒を取得する for /f "tokens=1 delims=." %%a in ('wmic os get localdatetime ^| find "."') do set datetime=%%a rem 新規作成するフォルダの名前を取得する set newFolder=%copyToParent%\バックアップ_%datetime% rem 新しいフォルダを作成する mkdir "%newFolder%" rem ファイルサイズの上限をメガバイト単位で指定する set fileSize=5 rem ファイルサイズの上限をバイト単位に変換する set /A maxBytes=%fileSize%*1024*1024 rem 指定された各フォルダに対して繰り返して処理を行うFor文 for %%i in (%*) do ( rem ドラッグされた各フォルダをコピーする(コピーするファイルサイズの上限を指定) robocopy "%%~i" "%newFolder%\%%~ni" /E /MAX:!maxBytes! ) rem setlocalコマンドによって変更されたローカル環境変数の設定を元に戻す endlocal
注目すべきコード①
最初に見て頂きたいのは4行目です。
rem コピー先のフォルダを指定する set copyToParent=C:\work\10_勉強\17_バッチファイル\0012\to
以上のコードは、コピー先のフォルダパスを取得するコードです。
バッチファイルにフォルダをドロップしてそのフォルダをコピーする先のフォルダパスを指定します。
注目すべきコード②
次に見て頂きたいのは7行目です。
rem 遅延環境変数展開を有効にする setlocal enabledelayedexpansion
コードの説明
以上のコードは、遅延環境変数展開を有効にする処理のコードです。
変数の値を変更する場合に、その変更がすぐに反映されない場合があります。
今回のコードではFor文の中で何度か変数への値の格納処理が行われるので、この遅延環境変数展開を有効にする必要があります。
注目すべきコード③
次に見て頂きたいのは10行目です。
rem 現在の年月日時分秒を取得する for /f "tokens=1 delims=." %%a in ('wmic os get localdatetime ^| find "."') do set datetime=%%a
コードの説明
以上のコードは、現在の年月日時分秒を取得する処理のコードです。
コードの詳細
①for、in、do
forはコマンドで、処理を繰り返すコマンドです。
For文はinとdoを組み合わせて使います。
inはFor文の構文の一部で、inの後にはループ処理の対象を指定します。
doもFor文の構文の一部で、doの後に指定されたコマンドを実行します。
②/f
「/f」はforコマンドのオプションです。
「/f」オプションはファイルまたはコマンドの実行結果を変数に読み込むときに使います。
今回はコマンド(wmic os get localdatetime)の実行結果を扱うので、「/f」オプションを使います。
③tokens=1
「tokens=1」は「wmic os get localdatetime」コマンドが返す値に対し、区切り文字で分けられる1番目の文字列の指定を表します。
もfし「tokens=2」なら2番目の文字列の指定を表します。
今回は年月日時分秒が欲しいので、「tokens=1」を指定しています。
④delims=.
「delims=.」は、区切り文字に「.」を指定する設定です。
「delims=」に「.」を結合させることで、「.」を区切り文字に指定することができます。
「wmic os get localdatetime」は現在の年月日時分秒を取得しますが、取得した値には、今回欲しい年月日時分秒以外に余計な文字列が含まれています。
今回欲しい年月日時分秒は「.」よりも前の文字列なので、「.」を区切り文字に指定して年月日時分秒だけを取得します。
「delims=.」を指定することで年月日時分秒だけを取得することができます。
⑤%%a
%%aは、inの後ろのコマンドが実行された後に、「.」を区切り文字として取得した1つ目のトークンの値を格納する変数です。
%%aの中の値は下のとおりです。
「.」を区切り文字に指定して取得された1つ目のトークの値である年月日時分秒の値が%%aに格納されています。
⑥wmic os get localdatetime
「wmic os get localdatetime」は現在のコンピュータのローカル日時を取得します。
「wmic os get localdatetime」だけ実行した結果は下のとおりです。
⑦^|
「^|」は、「wmic os get localdatetime」のコマンドと、「find “.”」のコマンドを連結させるものです。
「^|」を使って連結させることで、1行で「wmic os get localdatetime」と「find “.”」のコマンドを実行することができます。
順番は「wmic os get localdatetime」のコマンドを実行して次に「find “.”」のコマンドを実行します。
また、「|」の前に「^」(キャレット)を記述しているのは、「^」が無いと「|」が機能しないからです。
なので、「|」だけでなく「^」も記述しています。
⑧find “.”
「find “.”」は、対象から「.」の文字を検索するコマンドです。
今回は「wmic os get localdatetime」のコマンドが返す値から「.」の文字が含まれるデータを検索します。
「wmic os get localdatetime」のコマンドを実行した結果が下のとおりです。
「wmic os get localdatetime」のコマンドは、
「LocalDateTime」と「20240109104210.101000+540」の2行の値を返します。
このうち、2行目の「20240109104210.101000+540」が現在のコンピュータのローカル日時ですが、コンピュータのローカル日時には「.」の文字が含まれます。
年月日時分秒の値が含まれる「20240109104210.101000+540」の値だけが欲しいので「find “.”」コマンドを実行してこのコンピュータのローカル日時を取得します。
⑨set datetime=%%a
「set datetime=%%a」は%%aの値をdatetimeに格納する処理です。
注目すべきコード④
次に見て頂きたいのは13行目です。
rem 新規作成するフォルダの名前を取得する set newFolder=%copyToParent%\バックアップ_%datetime%
コードの説明
以上のコードは、新規作成するフォルダの名前を取得する処理のコードです。
今回作成する新規フォルダの名前は、「バックアップ_年月日時分秒」(※例:バックアップ_20240122113531)とします。
なので、「バックアップ_」の文字列と、年月日時分秒が格納された変数datetimeの値を結合させます。
注目すべきコード⑤
次に見て頂きたいのは16行目です。
rem 新しいフォルダを作成する mkdir "%newFolder%"
コードの説明
以上のコードは、新しいフォルダを作成する処理のコードです。
フォルダを新規作成する場合はmkdirコマンドを実行します。
mkdirコマンドの引数には、新規作成するフォルダのフルパスを指定します。
注目すべきコード⑥
次に見て頂きたいのは19行目から22行目です。
rem ファイルサイズの上限をバイト単位に変換する set /A maxBytes=%fileSize%*1024*1024
コードの説明
以上のコードは、ファイルサイズの上限値をメガ単位で指定するコードです。
コードの詳細
19行目でファイルサイズの上限値、または下限値を変数fileSizeに格納し、22行目で変数fileSizeに格納された値をメガ単位に計算して変数maxBytesに格納しています。
5メガ以上、または5メガ以下と指定する場合は、19行目に5と入力します。
注目すべきコード⑦
次に見て頂きたいのは25行目です。
rem 指定された各フォルダに対して繰り返して処理を行うFor文 for %%i in (%*) do (
コードの説明
以上のコードは、ドロップされたフォルダの数だけ処理を繰り返すfor文です。
今回の例では3つのフォルダをバッチファイルにドロップしますが、ドロップするフォルダの数が3つなので、3回処理を繰り返します。
①%%i
バッチファイルにドロップされたフォルダが代入されます。
②in
INはFor文とセットで使う構文で、INの後にバッチファイルにドロップされたフォルダ全てが指定されます。
③%*
%*には、バッチファイルにドロップされたフォルダ全てが格納されます。
④do
doはFor文とセットで使う構文です。
注目すべきコード⑧
次に見て頂きたいのは28行目です。
rem ドラッグされた各フォルダをコピーする(コピーするファイルサイズの上限を指定) robocopy "%%~i" "%newFolder%\%%~ni" /E /MAX:!maxBytes!
コードの説明
以上のコードは、robocopyコマンドを実行して、バッチファイルにドロップされたフォルダをコピー先にコピーする処理のコードです。
また、「/MAX」オプションを使い、コピーするファイルサイズの上限を指定します。
以上のコードでは「/MAX」オプションに変数maxBytesを指定していますが、「/MAX」オプションを使うと、robocopyコマンド実行時に変数maxBytesの値以上のファイルがコピーされなくなります。
今回はfileSizeに5を指定しているので、(5の値をメガバイトに変換した5メガ以上の)ファイルサイズのファイルがコピーされなくなります。
ちなみに、5の値をメガバイトに変換した値は下のとおりです。
第1引数:”%%~i”
第1引数である「”%%~i”」には、バッチファイルにドロップされたフォルダのフルパスが格納されています。
以下の画像だと、「C:¥work¥10_勉強¥17_バッチファイル¥0012¥from」配下の「data」「file」「xyz 2023」の3つのフォルダがバッチファイルにドロップされたので、「”%%~i”」には「data」「file」「xyz 2023」のうち「C:¥work¥10_勉強¥17_バッチファイル¥0012¥from¥data」の文字列(フルパス)が格納されます。
ちなみに「”」(ダブルクォーテーション)で囲っているのは、スペースを含むフォルダ名を認識させるためです。
フォルダ名にスペースが含まれていると、スペースの前後で2つの引数として認識されてしまうため、「”」(ダブルクォーテーション)で囲むことで1つの引数として認識させることができます。
第2引数:”%newFolder%¥%%~ni”
第2引数である「”%newFolder%¥%%~ni”」には、コピー先のパスが格納されています。
例えば「C:¥work¥10_勉強¥17_バッチファイル¥0012¥from」配下の「data」のフォルダがドロップされた場合、「”%newFolder%¥%%~ni”」には、「C:¥work¥10_勉強¥17_バッチファイル¥0012¥to¥バックアップ_20240122145618¥data」の文字列が格納されます。
※「20240122145618」は現在のコンピュータのローカル日時
「”%newFolder%¥%%~ni”」だと分かりづらいので、下のとおりに分解してみます。
- %newFolder%:新規作成したフォルダ
- ¥:パスの区切り文字「¥」
- %%~ni:ドロップされたフォルダのパスの最下層のディレクトリ
①%newFolder%
「%newFolder%」は、新規作成したフォルダです。
今回の例では、copyToに「C:¥work¥10_勉強¥17_バッチファイル¥0010¥to¥バックアップ_20240109104210」が格納されています。
②¥
「¥」はパスの区切り文字です。
③%%~ni
「%%~ni」は第1引数の「%%~i」に格納された、バッチファイルにドロップされたフォルダのフルパスの最下層ディレクトリです。
例えば「C:¥work¥10_勉強¥17_バッチファイル¥0010¥from」配下の「data」のフォルダがドロップされた場合、「%%~ni」には「data」の文字列が格納されます。
【オプション①】/E
「/E」のオプションは、ディレクトリまたはサブディレクトリが空であってもコピーする、というオプションです。
【オプション②】/MAXまたは/MIN
「/MAX」のオプションを付けて、そのあとスペース文字を1つ入れて値を指定(今回のコードでは変数maxBytesを指定)すると、robocopyコマンド実行時に、指定した値以上のファイルサイズのファイルがコピーされなくなります。
「/MIN」を使った場合は、指定した値以下のファイルサイズのファイルがコピーされなくなります。
動作確認
「フォルダの例」をご覧ください。
最後に
この記事では、バッチファイルにドロップした複数のフォルダを新規フォルダへコピーする方法についてご説明しました。
なお今回のバッチファイルは、フォルダをコピーする際は指定したファイルサイズでコピー制限するコードに盛り込みます。
フォルダをコピーする際にファイルサイズの制限を付けて、バッチファイルにドロップした複数のフォルダを新規フォルダへコピーしたい場合は本記事を参考にして頂けたら幸いです。
プログラミングのスキルを習得するなら
プログラミングのスキルを習得したい、今のスキルをもっと高めたい、そう考えているなら「プログラミングスクール」がおすすめです。
プログラミングのスキルの基礎を身につけるなら「TechAcademy」で1週間の無料体験があるので、これで「プログラミングの基礎」を学ぶのにおすすめですよ。