seq入門|連番を作ってループとテストデータを作る基本

seq入門|連番を作ってループとテストデータを作る基本

seq は、指定した範囲の連番を1行ずつ出力するだけのコマンドです。

たったそれだけの道具なのに、ループの回数を決めたりテストデータを用意したりする場面で、驚くほど手が早くなります。

私も検証用のファイルを何十個か作るとき、まず seq で数字の列を作ってからパイプでつなぐ のが手癖になりました。

似た書き方に bash のブレース展開 {1..5} がありますが、変数を混ぜた瞬間に展開されなくなるという落とし穴を抱えています。

その使い分けまで含めて、seq の基本を最小限だけまとめました。

手元の検証環境は GNU coreutils 8.32 / bash 5.2.37 です。

引数の数で3通りに変わる

seq は渡す引数の数だけで意味が変わります。

引数が1つなら1から始まり、2つなら開始値と終了値、3つなら真ん中が増分という並びです。

seq 5        # 1 から 5
seq 3 7      # 3 から 7
seq 0 5 20   # 0 5 10 15 20

実際に seq 0 5 20 を叩くと、0・5・10・15・20 の5行が返ってきました。

増分を負の数にすれば降順にもできるので、seq 5 -1 1 は 5 から 1 へ下りながら並びます。

小数も扱えて、seq 1 0.1 1.5 は 1.0 から 1.5 まで 0.1 刻みの6行になりました。

整数か小数かを事前に宣言する必要はなく、渡した値の書き方にそのまま合わせてくれる作りです。

見た目を整える3つのオプション

出力の見た目を変えるオプションは、3つ覚えておけば当面は足ります。

-w は桁をゼロ埋めでそろえ、-s は区切り文字を差し替え、-f は printf 形式の書式を指定するものです。

seq -w 8 11                  # 08 09 10 11
seq -s , 1 5                 # 1,2,3,4,5
seq -f 'log-%02g.txt' 1 3    # log-01.txt ...

seq -w 8 11 を実行すると 08・09・10・11 と2桁でそろい、ファイル名を並べたときに順番が崩れなくなりました。

-f は書式付きの文字列をそのまま作れるので、log-01.txt から log-03.txt までのファイル名が1行で用意できるわけです。

小数の桁をそろえたいときは seq -f '%.2f' 1 0.5 2 と書けば、1.00・1.50・2.00 が並びました。

なお -w と小数を組み合わせると、幅は小数点以下まで含めて数えられるため、seq -w 8 0.5 10 の先頭は 08.0 です。

変数を使うループでは seq が要る

bash には {1..5} と書くブレース展開があります。

seq を使わずに済むなら短くて良いのですが、展開の順番の都合で変数が使えないという制約があるのです。

N=5
echo {1..$N}      # {1..5} がそのまま出る
seq 1 $N          # 1 2 3 4 5

実際に N=5 を入れてから echo {1..$N} を叩くと、数字に展開されず {1..5} という文字列がそのまま返ってきました

ブレース展開は変数展開よりも先に処理される決まりなので、この順番はオプションでは変えられません。

回数が変数で決まるループを書くときは、素直に seq を挟むのが安全でしょう。

for i in $(seq 1 $N); do ...; done の形にしておけば、上限を後から変えても書き換えるのは1か所だけで済みます。

テストデータづくりに効く組み合わせ

seq が本領を出すのは、ほかのコマンドとつないだときです。

seq 1 3 | xargs -I{} echo "page={}" と書くと、page=1 から page=3 までが1行ずつ出力されました。

xargs入門|パイプの結果を次のコマンドの引数に渡す基本

同じ要領で seq -f 'file-%03g.txt' 1 20 | xargs touch とすれば、file-001.txt から file-020.txt までの空ファイルが一息で用意できます。

連番の生成と、その連番を食わせる処理を、別々のコマンドに分けて考えられるのが seq の気持ちよさ。

行数の多いダミーデータが欲しいときも、seq 1 100000 > big.txt のように一発で作れて便利です。

実際に seq 1 100000 | wc -l を通したところ、10万行が素直に返ってきたので、この規模なら待たされる感覚はありませんでした。

つまずきやすいポイント

まず、開始値が終了値より大きいと、seq は何も出さずに正常終了するという挙動があります。

seq 5 3 は1行も出力しないまま終了ステータス0を返すので、ループが空回りしていても気づきにくいのです。

降順が欲しいときは seq 5 -1 1 のように増分を明示するのが確実。

一方で増分に0を渡すと、seq: invalid Zero increment value: '0' というエラーで止まりました。

小数の刻みは内部で丸めが入るため、0.1 を足し続けた結果が想定とわずかにずれる場面もあります。

金額や時刻の計算に使うつもりなら、seq の出力をそのまま信じず、後段で丸め直しておくほうが安全でしょう。

最後に

seq は覚えることが少ないぶん、手が勝手に動くようになると効いてきます。

引数1つで1から、2つで範囲、3つで増分

この3つだけ押さえておけば、あとは -w-s を必要になったときに足すだけで済むでしょう。

ブレース展開が使えない場面の逃げ道として持っておく、という位置づけがいちばん実用的だと感じています。

まずは seq 1 5 | xargs -I{} echo {} あたりから、手元で叩いてみてください。

以上です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA