息子の写真を保存するフォルダを自動生成できたら楽ちん! と思って、Windowsのバッチファイルを書いてみました。(注:上級者向けです)
めっっちゃハマって、ググりまくりながら書いたので、詰まったところをメモします。
バッチファイル、クセ強すぎ・・・!
変数に値を代入するとき、変数名と値の前後に、余分な半角スペースを入れてはいけない
半角スペースを含んだ変数名や値になってしまいます。なんだそれ。
× SET year = 2021
○ SET year=2021
× IF 条件 ( SET filename=%filename%%year%_ )
○ IF 条件 (SET filename=%filename%%year%_)
変数に計算結果を代入するときは/aを付ける。変数は展開する
こんな感じ。展開しないと、変数名の文字列になってしまいました。
× SET month=month+1
× SET /a month=month+1
○ SET /a month=%month%+1
変数の中身を比較や計算したいときは%%で囲む
これも囲まないと展開されなくて、変数名の文字列として比較されちゃいます。
× IF start_day LSS 10
○ IF %start_day% LSS 10
比較演算子は英語
数値を比較するときは、=や>ではなく、EQUとかGTRとか使います。ぐぐったらでてくるよ!(思考停止)
FOR文は、%%i の扱いが面倒すぎるので、使わない! ラベルループを使う!(思考停止)
rem ○ ラベルループってこんな感じ
SET count=1
SET max_count=5
:loop
rem やりたい処理
SET /a count=%count%+1
IF %count% GTR %max_count% GOTO :eof
GOTO :loop
IF節の中で更新した変数を、そのIF節の中で比較や出力するときは、遅延展開を使う
該当行を”setlocal enabledelayedexpansion”および”endlocal”で囲って、変数は!!で囲んで展開します。
IF節はまるごと1行と認識されるらしく、デフォルトだとIF節の読み込み時に即時展開されてしまいます。まじかよ。
rem × これは期待した動きをしない
IF %last_day% GTR 31 (
SET /a month=%month%+1
rem 翌年に入った場合
IF %month% GTR 12 (
SET month=1
SET /a year=%year%+1
)
)
rem ○ これで期待通り
setlocal enabledelayedexpansion
IF %last_day% GTR 31 (
SET /a month=%month%+1
rem ↓ここ変わったよ
IF !month! GTR 12 (
SET month=1
SET /a year=%year%+1
)
)
endlocal
配列はないらしいので、変数のおしりに通し番号を付けて、配列もどきを作って使ったよ
配列もどきの変数を展開するときは、遅延展開の!!を使って、まず通し番号を展開→のちに変数全体を展開、と二段構えで展開するといいよ。
rem ○ こんな感じ
SET month_last_day=!month_last_day%month%!
文字化け対策(日本語名のフォルダを生成したい)
コマンドプロンプトはデフォルトがShift-JISらしく、UTF-8のバッチファイルを走らせると文字化けします。
文字コードを指定するコマンド(下記)をバッチファイル先頭に書いて解決(65001がUTF-8を示す)
rem × これだけだと化ける
mkdir "てすと"
rem ○ 化けない!
chcp 65001
mkdir "てすと"
完成したコード
無事こんなの出来ました!
1週間毎の開始日・終了日の入ったフォルダを、指定した日付を起点に、指定した数だけ生成します。各フォルダの中には「絞り込み」フォルダも生成されます。
楽になりました! ぱちぱち。
chcp 65001
rem 以下の変数を手動で設定し、コマンドプロンプトを起動して実行しましょう
rem 1週間毎の日付の入ったフォルダを、max_countの数だけ生成します
SET year=2021
SET print_year=false
SET month=9
SET month_last_day=30
SET month_0ume=09
SET start_day=20
SET max_count=13
rem うるう2月のフォルダを生成するなら、下の month_last_day2 も変更しましょう(使い終わったら元に戻してね)
SET month_last_day1=31
SET month_last_day2=28
SET month_last_day3=31
SET month_last_day4=30
SET month_last_day5=31
SET month_last_day6=30
SET month_last_day7=31
SET month_last_day8=31
SET month_last_day9=30
SET month_last_day10=31
SET month_last_day11=30
SET month_last_day12=31
SET count=1
setlocal enabledelayedexpansion
:loop
IF %print_year%==true (SET filename=%year%_%month_0ume%) ELSE (SET filename=%month_0ume%)
IF %start_day% LSS 10 (SET filename=%filename%0%start_day%-) ELSE (SET filename=%filename%%start_day%-)
SET /a last_day=%start_day%+6
rem 最後の日が翌月になった場合
IF %last_day% GTR %month_last_day% (
SET /a last_day=%last_day%-%month_last_day%
SET /a month=%month%+1
rem 翌年に入った場合
IF !month! GTR 12 (
SET month=1
SET /a year=%year%+1
SET filename=%filename%!year!_
)
IF !month! LSS 10 (SET month_0ume=0!month!) ELSE (SET month_0ume=!month!)
SET filename=!filename!!month_0ume!
)
IF %last_day% LSS 10 (SET filename=%filename%0%last_day%) ELSE (SET filename=%filename%%last_day%)
mkdir %filename%
cd %filename%
mkdir "絞り込み"
cd ..
SET /a start_day=%start_day%+7
IF %start_day% GTR %month_last_day% (
SET /a start_day=%start_day%-%month_last_day%
)
IF %start_day% EQU 1 (
SET /a month=%month%+1
IF !month! GTR 12 (
SET month=1
SET /a year=%year%+1
echo year=!year!
)
IF !month! LSS 10 (SET month_0ume=0!month!) ELSE (SET month_0ume=!month!)
)
SET month_last_day=!month_last_day%month%!
SET /a count=%count%+1
IF %count% GTR %max_count% GOTO :eof
GOTO :loop
endlocal
コメント