「試験用のcsvファイルを作るぞ~」
「ダミーユーザーが200人必要か…user1とかでいいか」
「Excelを使うのも面倒だし、batでちゃちゃっと書いちゃおう」
for /l %%i in (1,1,200) do echo user%%i>>hoge.csv
「これでよし」
「実行して、できたcsvをインポートしてと…」
user1
user10
user100
user101
user102
︙
user98
user99
「順番ぐちゃぐちゃやないかい」
こんな経験、一度はしたことがあるのではないだろうか。数値が文字列として処理されてしまうが故の事故である。
というわけで3桁の数値を順番に表示するため、こんな解決策を考えてみた。
if文を使った例
何かしらプログラミング経験のある人なら真っ先に思いつきそうなif関数を使った場合分け。
日ごろCやjavaを使ってる人にとってはbatは少し独特かもしれないので、その辺りを重点的に解説しよう。
と言ってもさほど難しい話ではない。
001,002…010,011…100,101…というように常に3桁になるように0で調整すれば、文字列順でも上手く表示されるはず。要は1桁のときは頭に0を2つ、2桁なら1つ、3桁ならつけなければよいのだ。
1桁のとき、2桁のとき、3桁のときと場合分けするならif分の出番だ。
for /l %%i in (1,1,200) do (
if %%i leq 99 (
if %%i leq 9 (
set Num=00%%i) else (
set Num=0%%i)) else (
set Num=%%i)
echo %Num%>>hoge.csv)
rem ↓出力結果(これはコメントアウトです)
rem ECHO は <ON> です。
これが第一の落とし穴である。
バッチファイルといっても結局はコマンドプロンプトに入力してるだけなので、上の例だと一行ずつ処理されてしまい、変な出力になる。
もちろん1行で書けばちゃんと読み取ってくれるのだが
for /l %%i in (1,1,200) do (if %%i leq 99 (if %%i leq 9 (set Num=00%%i) else (set Num=0%%i)) else (set Num=%%i) echo %Num%>>test.csv)
rem 読みづらい…
というわけで遅延環境変数君の出番である。詳しくはこの辺
を参考にしてほしいのだが、要はsetlocal enabledelayedexpansion
endlocal
で挟めば一括りで処理してくれる。
setlocal enabledelayedexpansion
for /l %%i in (1,1,200) do (
if %%i leq 99 (
if %%i leq 9 (
set Num=00%%i) else (
set Num=0%%i)) else (
set Num=%%i)
echo %Num%>>hoge.csv)
endlocal
rem 何も出力されない…
これも地味にわかりづらいポイントで、実は遅延環境変数はパーセント(%)ではなくエクスクラメーション(!)で囲まなくてはいけないのだ。
というわけでできあがったのがこちら。個々の関数についても後述する。
@echo off
chcp 65001
setlocal enabledelayedexpansion
for /l %%i in (1,1,200) do (
if %%i leq 99 (
if %%i leq 9 (
set Num=00%%i) else (
set Num=0%%i)) else (
set Num=%%i)
echo ユーザー!Num!>>hoge.csv)
endlocal
pause
関数の解説はこちら
解説
-
@echo off
- コマンドプロンプトでのコマンドの表示をオフにします。
-
setlocal enabledelayedexpansion
- 遅延環境変数の展開を有効にします。これにより、ループ内で変数の値を変更しても即座に反映されるようになります。
-
chcp 65001
- コードページをUTF-8に設定します。これにより、UTF-8エンコーディングの文字を正しく扱うことができます。
-
for /l %%i in (1,1,200) do ( ... )
- 言わずと知れたループ関数
- 基本構文は
for /l %%変数 in (開始,増分,終了) do (処理)
-
/l
以外のコマンドもある(今回は割愛) - 1から200までの数値を使ってループを実行します。
%%i
はループカウンタです。
-
if %%i leq 99 ( ... )
-
%%i
が99以下の場合の条件分岐です。
-
-
if %%i leq 9 ( ... )
-
%%i
が9以下の場合の条件分岐です。
-
-
set Num=00%%i
-
%%i
が9以下の場合、Num
変数に先頭に00を付けた値を設定します(例:001
,002
, ...)。
-
-
set Num=0%%i
-
%%i
が10以上99以下の場合、Num
変数に先頭に0を付けた値を設定します(例:010
,011
, ...)。
-
-
set Num=%%i
-
%%i
が100以上の場合、Num
変数にそのままの値を設定します(例:100
,101
, ...)。
-
-
echo ユーザー!Num!>>hoge.csv
-
ユーザー
という文字列にNum
変数の値を付け加えたものをhoge.csv
ファイルに追記します(例:ユーザー001
,ユーザー002
, ...)。 - この行を丸ごと
set /P X=ユーザー!Num!,<NUL >>hoge.csv
とすると改行無しで出ます。
一つのデータにたくさん属性を付けたいときなどに使えそうですね。
-
-
endlocal
-
setlocal
で設定したローカル環境を終了します。
-
-
pause
- スクリプトの実行を一時停止し、ユーザーの入力を待ちます。
このスクリプトは、1から200までの数値を持つユーザーIDを生成し、それをhoge.csv
ファイルに書き込むものです。各ユーザーIDは3桁のゼロパディング形式で出力されます。
Substrを使った例
と言っても実際にコマンドプロンプトにSubstrがあるわけではないのだが…
要は3桁と決まっているのだから、頭に0を付けたうえで、下から3桁切り出せばいいのだ。
1 → 001 → 001
10 → 0010 → 010
100 → 00100 → 100
rem こんなイメージ
切り出しの構文は %変数名:~開始位置,文字数%
数字の前にハイフン(-)を置くと反対向きになる。つまり下から切り出したいなら
echo %substr:~-3%>>hoge.txt
rem 最後まで、のときは文字数は指定しなくてもよい
00を頭に付ける、文字列の結合は文字列同士をつなげるだけでよい。
set str1=hoge
set str2=fuga
set substr=%str1%%str2%
echo substr
rem hogefuga
今回もまたfor文でループさせれば完成。
@echo off
setlocal enabledelayedexpansion
for /l %%i in (1,1,200) do (
set str1=00
set str2=%%i
set substr=!str1!!str2!
echo user!substr:~-3!>>hoge.txt)
endlocal
pause
今回も遅延環境変数は!で囲むのを忘れないように
以上