0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

バッチファイルで桁数そろえて001,002…099,100って出力したい

Last updated at Posted at 2024-11-28

「試験用のcsvファイルを作るぞ~」
「ダミーユーザーが200人必要か…user1とかでいいか」
「Excelを使うのも面倒だし、batでちゃちゃっと書いちゃおう」

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 何も出力されない…

 これも地味にわかりづらいポイントで、実は遅延環境変数はパーセント(%)ではなくエクスクラメーション(!)で囲まなくてはいけないのだ。

というわけでできあがったのがこちら。個々の関数についても後述する。

例文1
@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
関数の解説はこちら

解説

  1. @echo off

    • コマンドプロンプトでのコマンドの表示をオフにします。
  2. setlocal enabledelayedexpansion

    • 遅延環境変数の展開を有効にします。これにより、ループ内で変数の値を変更しても即座に反映されるようになります。
  3. chcp 65001

    • コードページをUTF-8に設定します。これにより、UTF-8エンコーディングの文字を正しく扱うことができます。
  4. for /l %%i in (1,1,200) do ( ... )

    • 言わずと知れたループ関数
    • 基本構文はfor /l %%変数 in (開始,増分,終了) do (処理)
    • /l以外のコマンドもある(今回は割愛)
    • 1から200までの数値を使ってループを実行します。%%iはループカウンタです。
  5. if %%i leq 99 ( ... )

    • %%iが99以下の場合の条件分岐です。
  6. if %%i leq 9 ( ... )

    • %%iが9以下の場合の条件分岐です。
  7. set Num=00%%i

    • %%iが9以下の場合、Num変数に先頭に00を付けた値を設定します(例:001, 002, ...)。
  8. set Num=0%%i

    • %%iが10以上99以下の場合、Num変数に先頭に0を付けた値を設定します(例:010, 011, ...)。
  9. set Num=%%i

    • %%iが100以上の場合、Num変数にそのままの値を設定します(例:100, 101, ...)。
  10. echo ユーザー!Num!>>hoge.csv

    • ユーザーという文字列にNum変数の値を付け加えたものをhoge.csvファイルに追記します(例:ユーザー001, ユーザー002, ...)。
    • この行を丸ごとset /P X=ユーザー!Num!,<NUL >>hoge.csvとすると改行無しで出ます。
      一つのデータにたくさん属性を付けたいときなどに使えそうですね。
  11. endlocal

    • setlocalで設定したローカル環境を終了します。
  12. pause

    • スクリプトの実行を一時停止し、ユーザーの入力を待ちます。

このスクリプトは、1から200までの数値を持つユーザーIDを生成し、それをhoge.csvファイルに書き込むものです。各ユーザーIDは3桁のゼロパディング形式で出力されます。

Substrを使った例

 と言っても実際にコマンドプロンプトにSubstrがあるわけではないのだが…
要は3桁と決まっているのだから、頭に0を付けたうえで、下から3桁切り出せばいいのだ。

1001001
100010010
10000100100
rem こんなイメージ

 切り出しの構文は %変数名:~開始位置,文字数%
数字の前にハイフン(-)を置くと反対向きになる。つまり下から切り出したいなら

切り出し
echo %substr:~-3%>>hoge.txt
rem 最後まで、のときは文字数は指定しなくてもよい

 00を頭に付ける、文字列の結合は文字列同士をつなげるだけでよい。

結合
set str1=hoge
set str2=fuga
set substr=%str1%%str2%
echo substr

rem hogefuga

今回もまたfor文でループさせれば完成。

例文2
@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

今回も遅延環境変数は!で囲むのを忘れないように


以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?