Bashシェルスクリプトでゼロ埋め(ゼロパディング)文字列を生成する方法いろいろ

2020-01-16Bash

はじめに

シェルスクリプト(Bash)で 数字の頭を 0 で詰めて、桁数を調整 したいことがよくあります。

ゼロ埋めゼロパディングゼロフィルゼロ詰めなどいろいろな呼び方をされます。
シェルスクリプトで実現する場合のいくつかの方法と使用例をまとめてみます。

検証環境

$ uname -moi
x86_64 MacBookPro11,4 Darwin

$ bash -version
GNU bash, バージョン 5.0.2(1)-release (x86_64-apple-darwin18.2.0)

printf コマンドを使う

セオリーというか、多くのプログラミング言語に搭載されている機能。
Bash組み込みコマンドの printf を使う方法があります。
出力フォーマットを指定することで、何桁の数値文字列として出力するか制御できます。

$ N=8

# 普通に表示
$ echo "${N}"
8

# printfを使うとゼロ埋めされるが、改行が出力されないことに注意。プロンプトかお尻にくっついちゃう
$ printf "%03d" "${N}"
008$

# 改行がほしい場合はこうする
$ printf "%03d\n" "${N}"
008

# 変数に代入して後々利用したい場合は以下の通り
$ S=$(printf "%03d\n" "${N}")
$ echo "${S}"
008

Bashの変数参照機能を使う

Bashの変数参照時に、不要な箇所を切り取ることができます。

$ N=8

# わざと0を3つ付与
$ X="000${N}"

# 参照時に後ろから3文字だけを取り出す
$ echo "${X: -3}"
008

※一度変数に代入しないといけないのが残念です。

連続したゼロ埋め数値を生成したい場合

ゼロ埋めした数値文字列は多くの場合、連続した値を処理するときに利用されます。

ex)
1 2 3 4 5
↓
001 002 003 004 005

連続したゼロ埋め数値を生成する方法もいくつかあります。

for ループを使う

for ループと printf を組み合わせて実現できます。

# そのまま表示するとこの様になる
$ for N in {1..5}; do
  echo $N
done

1
2
3
4
5

# printfを使ってゼロ埋め
$ for N in {1..5}; do
  printf "%03d\n" "${N}"
done

001
002
003
004
005

printfとワイルドカード展開を使う

printf は、書式(%03d の部分)よりも引数の数が多い場合、書式が繰り返し使用されることによって全ての引数が出力されます。

$ printf '%03d\n' {1..5}
001
002
003
004
005

seq コマンドのオプションを使う

seq コマンド自身にもゼロ埋めに利用できるオプションがあります。
-f オプションで、出力時のフォーマットを指定できます。

先の例のように、1から5の数値をゼロ埋めしてみます。

# 普通に表示
$ seq 1 5
1
2
3
4
5

# -f オプションで書式を指定できます。。
$ seq -f '%03g' 1 5
001
002
003
004
005

(もっと簡単)ワイルドカード展開だけ使う

ワイルドカード展開だけでも実現可能です。

$ echo {001..005}
001 002 003 004 005

これ、2桁や3桁になっても正常に動作するのか?という不安があったので試してみました。

$ echo {001..050}
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050

正常に動作していますね。

ひとこと

ワイルドカード展開、あまり使ったことがないのですが便利ですね。

2020-01-16Bash