seq コマンド入門 - 連番を生成してループに使う

seq コマンド入門 - 連番を生成してループに使う

この記事でできるようになること

  • `seq` で開始・終了・増分を指定して連番を作れる
  • `for i in $(seq ...)` で連番を使った繰り返し処理を書ける
  • `-w` のゼロ埋めと `{1..10}` との使い分けを説明できる

前提知識(先に読むと理解しやすい記事)

1 から 100 まで、手で打つ気ですか?

リナ: せんぱい、test1.txt から test100.txt まで 100 個ファイルを作りたいです。100 回コマンドを打つしかないのでしょうか。
ライニー先輩: 待って、それは大変すぎるよ。seq コマンドを使えば「1, 2, 3, ... 100」のような連番を一瞬で作れる。
ライニー先輩: ループと組み合わせれば、100 個のファイルも 1 行で作れるんだ。

言葉の整理(先に取りちがえを防ぎます)

  • 連番:1, 2, 3 のように続く数字の並びです。「シーケンス」も同じものを指します。
  • 引数:コマンドのうしろに書く値です。seq 55 が引数です。
  • 増分:いくつずつ増やすかを表す数です。「ステップ」「刻み」も同じ意味で使われます。
  • ループ:同じ処理をくりかえすしくみです。この記事では for を使います。
  • ゼロ埋め101 のように、けたをそろえるために先頭に 0 を足すことです。
  • 変数:値を一時的に入れておく箱です。この記事では i という箱に、連番を 1 つずつ入れます。
  • シェル入力したコマンドを解釈してコンピュータに実行させる対話プログラム。:ターミナルであなたの入力を受け取り、コマンドを動かす担当です。「bash」も同じものを指す呼び方です。

この記事でわかること

  • seq連番(1, 2, 3, ...)を作る 方法がわかります
  • 開始・終了・増分(ステップ) を指定する方法がわかります
  • for ループと組み合わせて くりかえし処理 を回せるようになります
  • -wけたをそろえる(ゼロ埋め)方法と、-s区切り文字を変える 方法がわかります
  • bash の {1..10} 記法との 使い分け がわかります

1. seq コマンドとは?

結論: seq は連続した数字(シーケンス)を 1 行に 1 つずつ出力するコマンド。seq 5 なら 1 から 5 までを生成する。

リナ: そもそも seq は何の略ですか。
ライニー先輩: sequence(シーケンス)の略だよ。連続・並び、という意味の英語だね。
ライニー先輩: いちばん簡単な使い方は、数字を 1 つだけ渡すこと。試しに seq 5 と打ってみよう。
$ seq 5
1
2
3
4
5
リナ: 1 から 5 までが縦に並んで出ました。
ライニー先輩: そう。数字を 1 つ渡すと「1 からその数まで」を出力するんだ。
ライニー先輩: 1 行に 1 つずつ出るのがポイントだよ。これをループに流しこむと、くりかえし処理になる。

2. 開始する数を変えるには?

結論: 引数を 2 つ渡すと seq 開始 終了 の意味になる。seq 3 7 なら 3 から 7 まで生成する。

リナ: 1 からではなく、5 から 10 までが欲しいときはどうしますか。
ライニー先輩: 数字を 2 つ並べるんだ。seq 5 10 で「5 から 10 まで」になる。
ライニー先輩: 引数の数で意味が変わる。ここが seq のおもしろいところだね。
$ seq 5 10
5
6
7
8
9
10

引数の数で意味が変わる

  • seq 終了 → 1 から終了まで
  • seq 開始 終了 → 開始から終了まで
  • seq 開始 増分 終了 → 増分(次章)を指定

3. 増分(ステップ)を指定するには?

結論: 引数を 3 つ渡すと seq 開始 増分 終了 の意味になる。seq 0 2 10 なら 0 から 10 まで 2 刻みで生成する。

リナ: 「2, 4, 6, 8」のように 1 つ飛ばしで出したいです。
ライニー先輩: 真ん中に増分を入れるんだ。いくつずつ増やすか、という数だね。
ライニー先輩: seq 2 2 10 と書けば「2 から 10 まで 2 きざみ」になるよ。
$ seq 2 2 10
2
4
6
8
10
リナ: 逆に、大きい数から小さい数へ数えることもできますか。
ライニー先輩: できるよ。増分をマイナスにするんだ。seq 5 -1 1 で「5, 4, 3, 2, 1」になる。
$ seq 5 -1 1
5
4
3
2
1

小数も使えます。seq 1 0.5 3 と書くと 1.0, 1.5, 2.0, 2.5, 3.0 のように 0.5 きざみで出ます。

小数がまじると、整数のほうも同じけた数にそろえて表示されます。

4. for ループで連番を使うには?

結論: for i in $(seq 1 5) の形で、生成した連番を 1 つずつ変数 i に入れて繰り返せる。連番ファイルの一括作成などに使う。

リナ: いよいよ 100 個のファイルを作る方法ですね。
ライニー先輩: for ループと seq を合体させるよ。$(seq 1 5) の部分は、seq を実行した結果に置きかわる。
ライニー先輩: つまり 1 2 3 4 5 になるんだ。それを 1 つずつ i に入れて、処理をくりかえす。
$ for i in $(seq 1 5); do
>   touch "test${i}.txt"
> done
$ ls
test1.txt  test2.txt  test3.txt  test4.txt  test5.txt
リナ: 5 個のファイルが一気にできました。これを 100 にすれば。
ライニー先輩: そう、seq 1 100 にするだけ。100 行打つ作業が 1 行で終わるんだ。

4-1. リナの失敗:$( ) を付け忘れる

先ほど作ったファイルを、いったん片づけてから試します。こうすれば、新しくできたファイルだけが見えます。

$ rm test1.txt test2.txt test3.txt test4.txt test5.txt
$ ls

ls に何も出ない状態から、もう一度やってみましょう。

リナ: 先輩、同じことをしたつもりなのに、変な名前のファイルができました。
$ for i in seq 1 5; do
>   touch "test${i}.txt"
> done
$ ls
test1.txt  test5.txt  testseq.txt
リナ: testseq.txt って何ですか。しかも 5 個できるはずが 3 個です。
ライニー先輩: $( ) が抜けているね。$( ) を付けないと、シェルは seq 1 5ただの 3 つの言葉 として読むんだ。
リナ: えっ、コマンドとして実行してくれないんですか。
ライニー先輩: そう。だから i には順に seq15 が入る。その結果が testseq.txttest1.txttest5.txt の 3 個なんだ。
リナ: なるほど、ファイル名を見れば何が起きたかわかるんですね。納得しました。
ライニー先輩: $( ) は「中のコマンドを実行して、その結果に置きかえる」という書き方。連番を回したいときは必ず付けてね。

seq は本サイトの仮想ターミナルにはまだありません。この記事の例は、手元の Linux やターミナルで試してください。

作ってしまったファイルは、名前を確かめてから消せます。消す前に必ず ls で対象を見てください。

$ ls test*.txt
$ rm test1.txt test5.txt testseq.txt

rm で消したファイルは、GUI とちがってゴミ箱に入りません。その場で完全に消えます。不安なときは rm -i を使ってください。1 件ずつ確認しながら消せます。

5. 桁をそろえる(ゼロ埋め)には?

結論: -w を付けると最大桁数に合わせて先頭をゼロで埋める。file01 file02 ... file10 のように桁がそろい、並び順が崩れない。

リナ: さっきの test1.txt から test100.txt を ls で並べたら、test1, test10, test100, test2 という順になりました。
ライニー先輩: それはけた数がばらばらだからだね。ls は名前を文字として左から見くらべる。だから 102 より前に来てしまうんだ。
ライニー先輩: -w を使うと 001 002 ... 100 のようにゼロ埋めしてくれる。width、つまり幅をそろえる、という意味だよ。
リナ: けたがそろえば、文字として並べても順番が崩れないんですね。
$ seq -w 1 10
01
02
03
04
05
06
07
08
09
10
リナ: 全部 2 けたにそろいました。
ライニー先輩: いちばん大きい数、ここでは 10 が 2 けただからね。それに合わせて全部 2 けたになるんだ。
ライニー先輩: 100 まで指定すれば 3 けた、つまり 001 から 100 にそろうよ。

ファイル作成と組み合わせるなら次のように書く。

for i in $(seq -w 1 100); do touch "log_${i}.txt"; done

log_001.txtlog_100.txt が桁そろえで作られる。

6. 区切り文字や書式を変えるには?

結論: -s で改行以外の区切り文字(カンマ・スペース等)に変えられる。-f で printf 形式の書式を指定できる。

リナ: 縦ではなく「1,2,3,4,5」と横に並べたいときはどうしますか。
ライニー先輩: -s を使う。separator、つまり区切り文字という意味だよ。-s , でカンマ区切りになる。
$ seq -s , 1 5
1,2,3,4,5
リナ: 横一列になりました。スペース区切りもできますか。
ライニー先輩: -s " " と書けばスペース区切りになるよ。
ライニー先輩: さらに -f を使えば、数字の前に文字を付けたり、けた数を決めたりもできる。
$ seq -f "page-%02g" 1 3
page-01
page-02
page-03

-f%g は数値を表す書式です。%02g02 は「2 けた・ゼロ埋め」という指定です。

ゼロ埋めだけが目的なら、前の章の -w のほうが手軽です。-f は数字の前に文字を付けたり、小数のけたを決めたりできます。

7. bash の {1..10} とどう違う?

結論: bash には連番を作る {1..10} という記法もある。固定値なら {1..10} が速い。範囲を変数で指定したいときseq を使う。

リナ: 前に echo {1..5} で連番が出るのを見たことがあります。seq と何がちがうのですか。
ライニー先輩: いいところに気づいたね。{1..5} は bash のブレース展開というしくみで、seq より速いんだ。
ライニー先輩: ただし弱点がある。変数を使うと展開されない んだよ。
$ echo {1..5}
1 2 3 4 5
$ n=5
$ echo {1..$n}
{1..5}
リナ: あれ、{1..$n} は連番にならず、そのまま文字で出てしまいました。
ライニー先輩: そう。ブレース展開は、変数を入れると動かないんだ。
ライニー先輩: いっぽう seq なら seq 1 $n で変数がきちんと効く。だから、くりかえす回数が変数で決まる場面では seq が活躍するよ。
$ n=5
$ seq 1 $n
1
2
3
4
5

for i in $(seq 1 $n) は、大きな数を指定すると連番すべてをメモリに広げます。

数万から数百万回のループなら、for ((i=1; i<=n; i++)) という算術ループのほうが効率的です。ふだんの数十から数千回くらいなら seq で問題ありません。

8. よくあるつまずきと対処

結論: つまずきの大半は「引数の数の勘違い」「$( ) の付け忘れ」「ゼロ埋め忘れによる並び順崩れ」の 3 つ。

症状 原因 対処
思った範囲と違う数が出る 引数の数で意味が変わるのを誤解 seq 開始 増分 終了 の順序を確認
ループが seq 1 5 の文字列を回す $( ) を付け忘れた for i in $(seq 1 5) と書く
ファイルの並び順が崩れる ゼロ埋めしていない seq -w で桁をそろえる
{1..$n} が連番にならない ブレース展開は変数非対応 seq 1 $n を使う
横並びにしたいのに縦に出る デフォルトの区切りが改行 -s ,-s " " で区切り文字を変更

やってはいけないこと

  • とても大きな範囲を $(seq ...) で一気に広げて、メモリを圧迫します
  • ゼロ埋めをせずに連番ファイルを作り、あとで並び順に悩みます

9. ミニ課題:実際にやってみよう

結論: きざみの指定・ゼロ埋め・ループとの組み合わせの 3 問で、seq の使い方を手で確かめる。

リナ: 使い方はわかりました。手を動かして確かめたいです。
ライニー先輩: いいね、3 問用意したよ。まず練習用のディレクトリファイルをまとめて整理する入れ物。Windows や macOS の「フォルダ」と同じもの。を作って、その中で試してみて。
$ mkdir -p ~/seq-practice && cd ~/seq-practice

課題 1:10 から 1 へ向かって、2 ずつ減る数を表示しよう。

ヒント 1(方向づけ)を見る

引数を 3 つ書きます。減らしたいので、真ん中の数はマイナスにします。

ヒント 2(コマンド名)を見る

使うのは seq です。引数は seq 開始 増分 終了 の順に書きます。

答えを見る
$ seq 10 -2 1
10
8
6
4
2

終わりの数は 1 ですが、2 の次は 0 になり 1 を下回ります。だから最後は 2 で止まります。

課題 2:1 から 12 までを、2 けたのゼロ埋めで表示しよう。

ヒント 1(方向づけ)を見る

けたをそろえるためのオプションが 1 つあります。第 5 章で出てきました。

ヒント 2(コマンド名)を見る

使うのは seq です。けたをそろえるオプションは width の頭文字です。

答えを見る
$ seq -w 1 12
01
02
03
04
05
06
07
08
09
10
11
12

いちばん大きい数が 12 で 2 けたなので、全体が 2 けたにそろいます。

課題 3report_01.txt から report_12.txt までの 12 個のファイルを、けたをそろえて一括作成しよう。

ヒント 1(方向づけ)を見る

課題 2 で作った連番を、ループに流しこみます。ファイルを作るコマンドと組み合わせます。

ヒント 2(コマンド名)を見る

使うのは for ループと touch です。ループに seq の結果を渡すときの書き方を、第 4 章で確かめてください。

答えを見る
$ for i in $(seq -w 1 12); do touch "report_${i}.txt"; done
$ ls report_*.txt | head -n 3
report_01.txt
report_02.txt
report_03.txt

作られた数も確かめてみましょう。

$ ls report_*.txt | wc -l
12

練習が終わったら、作ったディレクトリごと片づけられます。中身を確かめてから消してください。

$ cd ~
$ ls ~/seq-practice
$ rm -r ~/seq-practice

rm -r はディレクトリを中身ごと消します。実行する前に、パスファイルやディレクトリの場所を表す文字列。~/seq-practice であることを必ず確かめてください。

10. 振り返り

リナ: 整理します。seq は引数の数で意味が変わるんですね。1 つなら終わり、2 つなら開始と終わり、3 つなら間が増分。
ライニー先輩: そのとおり。ここを覚えておけば、思ったとおりの範囲が出せるよ。
リナ: ループで使うときは $( ) を必ず付ける。ファイル名をそろえたいときは -w ですね。
ライニー先輩: 完璧だね。範囲を変数で決めたいときは {1..10} ではなく seq を使う。そこも忘れずに。

今日の 3 行まとめ

  1. seq は引数の数で意味が変わる。seq 終了 / seq 開始 終了 / seq 開始 増分 終了
  2. ループで使うときは $( ) を付ける。忘れると seq という文字がそのまま回る
  3. けたをそろえたいときは -w。範囲を変数で決めたいときは {1..10} ではなく seq

まとめ / 次に読む

この記事を共有

次の一手