バッチファイルを使ってファイル名に連番をつける方法をメモメモ…
たとえばテキストファイルが複数あるときに、それぞれのファイル名を MyText1.txt、MyText2.txt、MyText3.txt … のような連続した数字でリネームしたい場合の対処法です。もちろんファイル名だけではなくフォルダ名にも適用できます。
バッチファイルの作成方法
バッチファイルの作り方は簡単です。テキストドキュメントを新規作成し、適当なエディタ(メモ帳など)を使ってコマンドを書き、拡張子を .bat に変更して保存しなおすだけです。詳しい手順は前回の投稿で書いたので必要であれば参考にしてください。
コマンド
バッチファイルの内容はこんな感じです。
setlocal enabledelayedexpansion set prefix=MyFile set num=0 for %%F in (%*) do ( set extention=%%~xF ren %%F !prefix!!num!!extention! set /a num+=1 ) endlocal
ファイルやフォルダをバッチファイル(.bat)上にドラッグ&ドロップすると、自動的に MyFile0、MyFile1、MyFile2 …とリネームされるはずです。"MyFile" の部分を変更したい場合はset prefix=のうしろを好きな文字列に書き換えてください(スペースを含む場合はダブルクォーテーション " " でくくります)。開始番号を 0 からではなく別の数字にしたい場合はset num=のあとの数字を変更すればOKです。
ポイントとしてはやはり1行目のsetlocal enabledelayedexpansionでしょうか。バッチファイルではループ処理などでの変数を読み込むタイミングが他の言語とは異なります。そのため、7~9行目のループ内の処理がきちんと順番に実行されるように遅延環境変数の展開を有効化する必要があるというわけです。遅延環境変数については次のページの解説がわかりやすかったです。
バッチファイル界の魔境『遅延環境変数』に挑む(おまけもあるよ) - Qiita
注意点としては、多数のファイルを一度にD&Dした場合に、コマンドの文字数制限にひっかかってしまいうまく実行できない場合があるということです。そういう場合はディレクトリから直接ファイルを探して取得するようにしたほうがいいかもしれません。たとえば6行目の(%*)を(*.txt)と変更するとD&Dしたファイルではなく同一ディレクトリ内のすべてのテキストファイルを対象にできます。
それから、対象のファイルに特殊な文字列が含まれていた場合、そのファイル名自体がコマンドとして読み込まれてしまいエラーになることがあるそうです(参考ページ)。滅多に起きないとは思いますが一応書き留めておきます。
コマンド (ゼロ埋め)
ついでと言ってはなんですが、指定した桁数になるようにゼロ埋めする場合のコードも書いてみました。
setlocal enabledelayedexpansion set prefix=MyFile set pad=3 set num=0 for %%F in (%*) do ( set padnum=00000000!num! set extention=%%~xF ren %%F !prefix!!padnum:~-%pad%!!extention! set /a num+=1 ) endlocal
数字の前にいくつかゼロをくっつけてから指定した桁数で切り取るという処理を行っています。桁数は4行目のset pad=で指定可能です。MyFile1 は MyFile001、MyFile10 は MyFille010 というように桁を揃えることができます。
コマンド (ゼロ埋め&ファイル名の重複を避ける)
コメント欄でリクエストがあったので「同一ディレクトリにすでに同じ名前のファイルがあった場合は自動的に別の数字をつける」という機能も実装してみました。使い方はこれまで同様バッチファイル上にD&Dするだけです。
setlocal enabledelayedexpansion set prefix=MyFile set tempprefix=temp_ set pad=3 set num=0 for %%F in (%*) do ( ren %%F "!tempprefix!%%~nxF" ) for %%F in (%*) do ( call :rename "%%~dpF!tempprefix!%%~nxF" ) exit /b :rename set file=%1 set path=%~dp1 set extention=%~x1 :again set padnum=00000000!num! set newname=!prefix!!padnum:~-%pad%!!extention! if exist !path!!newname! ( set /a num+=1 goto again ) ren !file! !newname! set /a num+=1 exit /b endlocal
たとえば MyFile000 MyFile001 MyFile002 NewFile1 NewFile2 という5つのファイルが同じフォルダの中にあった場合、数字が重複しないように MyFile000 MyFile001 MyFile002 MyFile003 MyFile004 というふうにリネームします。別のフォルダに入ったファイルや拡張子の違うファイルだとうまく機能しないので注意。
技術的なポイントとしては
- もしも名前変更したいファイルの中にすでに名前変更後のものが含まれていた場合ややこしいことになるので、一旦ファイル名の先頭に適当な文字列をくっつけて別の名前にしておく(MyFile000 → temp_MyFile000)。文字列は既存のファイル名と重ならないようにset tempprefix=で指定。
- ファイル名が存在するかどうかのチェックは24行目のif existで行う。重複していればgotoで20行目まで戻って重複しなくなるまで数字を増やす。
- バッチファイルでは、forループ構文の中でgotoを使うとその時点でカウント変数%%Fが破棄されループも解除される仕様。実際の処理はcallを使ってサブルーチンとして呼び出す。
正直バッチファイルだけでここまで複雑な処理をしたことがないので、これで正解なのかはわかりません(もっとシンプルな方法があるかも…)。もしかしたら不具合が出る可能性もあるので確認しながら使ってください。
コマンド (フォルダ内のファイルをシャッフル)
コメント欄でリクエストがあった「フォルダ内のファイルをシャッフル(ランダムに並び替え)してその上で連番にリネームする」という処理です。好きなフォルダ(複数指定可)をバッチファイル上にD&Dすると、その中のすべてのファイルがリネームされます。
set prefix=MyFile set startNum=0 set pad=3 for %%A in (%*) do ( cd %%~fA setlocal enabledelayedexpansion @rem フォルダ内のすべてのファイルをランダムな数値でリネームする for %%B in (*) do ( set extention=%%~xB ren "%%B" !random!!extention! ) @rem フォルダ内のすべてのファイルを連番でリネームする set num=!startNum! for %%B in (*) do ( set padnum=00000000!num! set extention=%%~xB ren "%%B" !prefix!!padnum:~-%pad%!!extention! set /a num+=1 ) endlocal )
13行目では組み込み変数randomを使って0~32767の範囲の整数値を取得しています。なお、システム環境によってはループ処理が名前順に実行されず、うまく動作しない場合があるかもしれません。そのときは dir コマンドの /o:n オプションを利用するなどさらにひと手間必要になります。
はじめまして! 近江と申します。
返信削除記事を参考させていただきました。パソコン歴はもう40年位になりますが、DOSコマンドは遠の昔に忘れてしまい、大変助かりました。大昔は640MBの壁をいかに超えるかなどEMSをいじって楽しんでましたが今では齢60歳となり昔の記憶が段々と薄れてきています。WindowsになってMS-DOSのコマンド(正式にはパワーシェルでしょうが・・・)の基本を経験して良かったと感じています。また、何かの折には拝見させていただきます。
この度は、ありがとうございました。
https://asamai-cts.jp 近江
こんばんは
返信削除ひとつわからない事があるのですが
5つのファイルがあり
名前01
名前02
名前03
名前04
名前05
ってなったんですがたとえば後からもう1つファイル増えた場合で後から増えたファイルにパッチ当てると名前01になると思うのですが、これを同フォルダ内に入れて増えたファイルだけパッチあてて同名前がある場合(今回の場合名前01~05が既にあるため)自動で名前06ってなるようにできたりしますか?
説明下手ですみません
やっぱり後から増えたファイル含めて全部まとめてパッチ当てなおすしかないですか?
全部当てなおすと名前01~名前06になりますがほんの少しだけ手間で....
記事の最後に追記しました!
削除これを使って新しいファイルにバッチ処理をあてると、同じフォルダの中にある他のファイルと重複しないようなファイル名がつけられる…はず…です。もしうまく動作しなかったらスミマセン…
ありがとうございます。思ってたやつです。
削除こんなに早く対応してもらえると思ってませんでした。
ホントに助かります。
ブラウザ上で動くピアノ(いつもはスマホでやってるけど使いずらいので)とか他にも色々参考にしてるので
今後もブログ拝見してるので頑張ってください
ありがとうございました。
はじめまして!
返信削除CornPOPPA様、痒い所に手が届くバッチファイルを公開してくださりありがとうございます。 現在私は、フォルダ内に保存された音楽や画像などを毎回ファイルをシャッフルして連番としてリネームして、スライドショー的な操作をしたいと考えており調べてましたら、こちらのサイトに辿り着きました。
CornPOPPA様のバッチ処理内に「毎時フォルダ内のファイルをシャッフル(shuf)して連番リネームする処理(フォルダをD&Dしてフォルダ内のファイルを処理)などは可能でしょうか?
プログラム的なことはド素人で、毎回ネット内を調べ、公開してくださっている方のを使わせて頂いております。
下記は、英語圏を含め探していたところですが、すべてファイル名をランダムに書き換えてしまうものばかりで思ったものが見つからずです。
How to shuffle file names randomly in a directory
https://unix.stackexchange.com/questions/506302/how-to-shuffle-file-names-randomly-in-a-directory
Randomly Shuffle File Names in a Folder
https://www.reddit.com/r/Batch/comments/gt4u27/randomly_shuffle_file_names_in_a_folder/
How can I arrange all the image files in an folder randomly?
https://stackoverflow.com/questions/52457832/how-can-i-arrange-all-the-image-files-in-an-folder-randomly
バッチファイル : ファイル順のシャッフル
https://logicalerror.seesaa.net/article/128449047.html
⇧
こちらもファイル名をランダムで書き換えていますが、毎回シャッフルしてここにCornPOPPA様のバッチ処理が組み込めないかと、見よう見まねでチャレンジしてみましたが、バッチコード、構文が書けないので断念しております。
もし可能でしたら毎回バッチを実行後に「シャッフル連番リネーム」させることはできないでしょうか? お手数ではございますが、お力をお貸し頂けると幸いです。
記事の最後に追記しました!
削除フォルダを指定すると、その中のファイルをシャッフルし、さらに連番でリネームします。
CornPOPPA様、お礼の返事が大変遅くなりました。 作ってくださりありがとう御座います。 早速試してみて、ちゃんと入れ替わっているので、何度も繰り返して眺めながら凄ーい!と感動してます。 これで毎回、雰囲気も気持ちも変えられ、楽しめる環境が得られました。 この度は、本当にありがとうございました。
削除はじめまして。
返信削除ファイル名に連番をつけるという処理が必要になり手作業((+_+))、、、と途方に
くれていたところ、こちらの記事に辿りつき活用させていただいております。
ほんとにありがとうございます。
その中で一つ質問があるのですが、既にデータファイルに名前を付けている
ファイル名に連番の数字だけ追記したいのですが可能でしょうか。
自分でも試行錯誤し、
3行目の set prefix=MyFileを消したりしたのですが
全くうまくいかなくて、、、、( ;∀;)
その都度set prefix=MyFileのMyFileを変更すればいいのですが、
ファイル名の最初に記号(●など)を表記することがあり
その際、文字化けするので起動バッチを使用する前に
自分でファイル名は変更し後で連番を付けたいと考えてります。
お忙しいところ恐縮ですが、ご存知であれば教えていただきたいです。
よろしくお願いいたします。
既存のファイル名に番号を追記したい場合は
削除ren %%F !prefix!!num!!extention!
の部分を
ren %%F %%~nF!num!!extention!
と書き換えてみてください。%%~nFは「拡張子を除くもとのファイル名」という意味です。これで「ABC.txt」という名前のファイルが「ABC1.txt」のようにリネームされます。基本的にはこの行を変更すれば好きなファイル名をつけることが可能です。たとえば
ren %%F %%~nF_!num!!extention!
とすれば「ABC_1.txt」のようにもとのファイル名と番号の間にアンダースコア(_)を追加できます。