1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

バッチファイルでゼロ埋めする(桁数可変)

Last updated at Posted at 2021-04-19

Y子です。
今回は、ゼロ埋めの方法を考えます。

【ゼロ埋め(`zero padding`)とは】ゼロを使って数字の桁数を合わせることを言います。 たとえば「`1`」「`20`」「`1000`」を、「`0001`」「`0020`」「`1000`」と書いて桁数を合わせます。 そうすることで、見栄えが揃うほか、ソートしやすくもなります。

#概要・用途
対象文字列の頭にゼロを結合して、意図する桁数の文字列にします。
たとえば、分割したファイルのファイル名末尾に付加する用途を想定します。
確認環境:Windows 10 Home (Bld. 19042.928)

#コード
##(1) シンプルな例
対象の数字を引数から取得する例です。
対象の数字の左側に、「0000」のようなゼロだけの文字列を結合し、その後右側から必要な長さを切り出します。

ゼロ埋め後の桁数は、ハードコードで「4桁」としました。
違う桁数にしたい場合は、この2か所を変えてください。

  • zeros」に入れるゼロの個数
  • 最後の処理の「%number:~-4%」の数字を変えてください。

※ゼロの個数は、本当はn-1個でいいんですが、同じ数の方が見やすい気がしますし、多い分には問題にならないので、このようにしました。

zeropad1.bat
@echo off

rem 引数がない場合は終了する
if "%~1"=="" (echo 引数がありません & pause & exit /b)

rem 対象の数字
set number=%1
rem ゼロ埋め用文字列(4桁)
set zeros=0000

rem ゼロ埋め用文字列と引数を結合
set number=%zeros%%number%

rem 既定の桁数に削り(右から4桁)、出力
echo %number:~-4%

実行してみます。

実行結果
> zeropad1.bat 1
0001
> zeropad1.bat 123
0123
> zeropad1.bat 12345
2345

「4桁」固定で文字列を切り出しているので、「12345」のように5桁以上の数字を与えると__答えが変わってしまいます__。
用途や環境によって、あらかじめ適切な桁数を設定する必要があります。

##(2) 欲張り仕様
以下のような仕様を追加してみます。

  • 桁数は可変とし、引数で与える
  • 対象文字列の桁数以下で削らない

昨日の「バッチファイルで文字列長を取得する」サブルーチンを使って、桁数を判定します。

zeropad2.bat
@echo off

rem 引数がない場合は終了する
if "%~2"=="" (echo 引数がありません & pause & exit /b)

rem 遅延環境変数の展開を有効にする
setlocal enabledelayedexpansion

rem 対象の数字、ゼロ埋め後の桁数、ゼロ埋め用文字列(初期化)
set number=%1
set keta=%2
set zeros=

rem 指定の桁数が対象の数字以下の場合はゼロ埋め不要 → 最後に飛ぶ
set strlen=0
call :get_strlen %number%
if %keta% leq %strlen% (goto :result)

rem ループをketa回まわして、必要な長さのゼロを作る
for /l %%a in (1,1,%keta%) do set zeros=!zeros!0

rem ゼロ埋め用文字列と引数を結合
set number=%zeros%%number%

rem 右からketa桁を切り出して、出力
call set number=%%number:~-%keta%%%

:result
echo %number%
exit /b

rem ====サブルーチン====
rem 文字列長を取得する
:get_strlen
  set str_in=%~1
  
  :label_top
  rem 長さ加算
  set /a strlen+=1
  rem 1文字減らす
  set str_in=%str_in:~1%
  rem 文字列がなくなったら終了
  if not "%str_in%"=="" (goto :label_top)
exit /b

1行のfor文でゼロの桁数を調整したり、callを使って変数の中で変数を展開してみたり、かなりオシャレになりました。
※後者は__「2回解釈させる」__というワザみたいです。勉強になりました。

では実行してみます。

実行結果
> zeropad2.bat 1 4
0001
> zeropad2.bat 123 4
0123
> zeropad2.bat 12345 4
12345
> zeropad2.bat 12345 20
00000000000000012345

長い数字を与えても削りすぎませんし、大きい桁数も正しく出力できました。いいですね。

#おわりに
(2)で高機能なバッチを作りましたが、ゼロ埋め処理を単独で使うことは少ない気がしますので、コンパクトな(1)の桁数を調整して使った方が、使いやすいコードになりそうですね、実は。
まあでも!道具が増えて、達成感と自己肯定感が爆上がりですよ!
自己肯定感が大事ってしょこたんも言ってますし!

ではでは!

1
3
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
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?