seq コマンド入門 - 連番を生成してループに使う
1 から 100 まで、手で打つ気ですか?
seq コマンドを使えば「1, 2, 3, ... 100」みたいな連番を一瞬で作れるんだ。ループと組み合わせれば 100 個のファイルも 1 行で作れるよ。この記事でわかること
seqで 連番(1, 2, 3, ...)を生成 する方法- 開始・終了・増分(ステップ) を指定する方法
forループと組み合わせて 繰り返し処理 を回す方法-wで 桁をそろえる(ゼロ埋め)、-sで 区切り文字を変える 方法- bash の
{1..10}記法との 使い分け
1. seq コマンドとは?
結論:
seqは連続した数字(シーケンス)を 1 行に 1 つずつ出力するコマンド。seq 5なら 1 から 5 までを生成する。
seq 5 と打ってみよう。$ seq 5
1 2 3 4 5
2. 開始する数を変えるには?
結論: 引数を 2 つ渡すと
seq 開始 終了の意味になる。seq 3 7なら 3 から 7 まで生成する。
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 刻みで生成する。
seq 2 2 10 で「2 から 10 まで 2 刻み」だよ。$ seq 0 2 10
0 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, 1.5, 2, 2.5, 3 のように 0.5 刻みで出力される。
4. for ループで連番を使うには?
結論:
for i in $(seq 1 5)の形で、生成した連番を 1 つずつ変数iに入れて繰り返せる。連番ファイルの一括作成などに使う。
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
seq 1 100 にするだけ。100 行打つ作業が 1 行で終わる。これが連番生成の威力だね。for i in $(seq ...) の $( ) を忘れて for i in seq 1 5 と書くと、seq 1 5 という 3 つの文字列をそのまま回してしまう。コマンドを実行した結果に置き換えるための $( ) は必須。
5. 桁をそろえる(ゼロ埋め)には?
結論:
-wを付けると最大桁数に合わせて先頭をゼロで埋める。file01file02...file10のように桁がそろい、並び順が崩れない。
ls で並べたら test1, test10, test100, test2... と変な順番になりました...-w(width=幅をそろえる)を使うと、001 002 ... 100 のようにゼロ埋めしてくれる。文字として並べても順番が崩れないよ。$ seq -w 1 10
01 02 03 04 05 06 07 08 09 10
ファイル作成と組み合わせるなら次のように書く。
for i in $(seq -w 1 100); do touch "log_${i}.txt"; donelog_001.txt 〜 log_100.txt が桁そろえで作られる。
6. 区切り文字や書式を変えるには?
結論:
-sで改行以外の区切り文字(カンマ・スペース等)に変えられる。-fで printf 形式の書式を指定できる。
-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 は数値を表す書式。%02g の 02 は「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 で問題ない。
ミニ課題(クリックで開く)
report_01.txt から report_12.txt までの 12 個のファイルを、桁そろえ(2 桁)で一括作成してみよう。
ヒント: -w で桁をそろえ、for ループと touch を組み合わせる。for i in $(seq -w 1 12); do touch "report_${i}.txt"; done
8. よくあるつまずきと対処
結論: つまずきの大半は「引数の数の勘違い」「
$( )の付け忘れ」「ゼロ埋め忘れによる並び順崩れ」の 3 つ。
| 症状 | 原因 | 対処 |
|---|---|---|
| 思った範囲と違う数が出る | 引数の数で意味が変わるのを誤解 | seq 開始 増分 終了 の順序を確認 |
ループが seq 1 5 の文字列を回す |
$( ) を付け忘れた |
for i in $(seq 1 5) と書く |
| ファイルの並び順が崩れる | ゼロ埋めしていない | seq -w で桁をそろえる |
{1..$n} が連番にならない |
ブレース展開は変数非対応 | seq 1 $n を使う |
| 横並びにしたいのに縦に出る | デフォルトの区切りが改行 | -s , や -s " " で区切り文字を変更 |
やってはいけないこと
- 巨大な範囲(数百万)を
$(seq ...)で一気に展開してメモリを圧迫する - ゼロ埋めせずに連番ファイルを作り、後で並び順に悩む