seq Command: Generating Sequences of Numbers

seq Command: Generating Sequences of Numbers

Going to Type 1 Through 100 by Hand?

Lina: Senpai, I need to create test1.txt all the way to test100.txt. Do I really have to type the command 100 times?
Linny-senpai: Hold on, that would be painful. The seq command builds a sequence like "1, 2, 3, ... 100" in an instant. Combine it with a loop and you can create all 100 files in a single line.

What You'll Learn

  • How to generate a sequence of numbers (1, 2, 3, ...) with seq
  • How to set the start, end, and increment (step)
  • How to combine it with a for loop to repeat tasks
  • How to pad with zeros using -w and change the separator with -s
  • When to use seq vs bash's {1..10} notation

1. What Is the seq Command?

Conclusion: seq prints a sequence of numbers, one per line. seq 5 generates 1 through 5.

Lina: What does "seq" even stand for?
Linny-senpai: It's short for sequence. The simplest use is passing a single number. Try typing seq 5.
$ seq 5
1
2
3
4
5
Lina: The numbers 1 to 5 appeared in a column.
Linny-senpai: Right. Pass one number and it prints "1 up to that number," one value per line. Feed that into a loop and it becomes a repeating task.

2. How Do I Change the Starting Number?

Conclusion: Pass two arguments and it means seq START END. seq 3 7 generates 3 through 7.

Lina: What if I want 5 to 10 instead of starting from 1?
Linny-senpai: Line up two numbers: seq 5 10 means "5 through 10." The neat thing about seq is that the number of arguments changes its meaning.
$ seq 5 10
5
6
7
8
9
10

The argument count changes the meaning

  • seq END → 1 to END
  • seq START END → START to END
  • seq START STEP END → set an increment (next section)

3. How Do I Set the Increment (Step)?

Conclusion: Pass three arguments and it means seq START STEP END. seq 0 2 10 generates 0 through 10 in steps of 2.

Lina: I want to print every other number, like "2, 4, 6, 8."
Linny-senpai: Put the increment (how much to add each time) in the middle. seq 2 2 10 means "2 through 10 in steps of 2."
$ seq 0 2 10
0
2
4
6
8
10
Lina: Can I count down from a big number to a small one?
Linny-senpai: Yes. Make the increment negative. seq 5 -1 1 counts down "5, 4, 3, 2, 1."
$ seq 5 -1 1
5
4
3
2
1

It handles decimals too. seq 1 0.5 3 outputs 1, 1.5, 2, 2.5, 3 in steps of 0.5.

4. How Do I Use a Sequence in a for Loop?

Conclusion: Write for i in $(seq 1 5) to feed each generated number into the variable i and repeat. Great for creating numbered files in bulk.

Lina: Finally, the way to create 100 files!
Linny-senpai: We combine a for loop with seq. The $(seq 1 5) part is replaced by seq's output (1 2 3 4 5). Each value goes into i and the body repeats.
$ for i in $(seq 1 5); do
>   touch "test${i}.txt"
> done
$ ls
test1.txt  test2.txt  test3.txt  test4.txt  test5.txt
Lina: Five files appeared at once! So if I change it to 100...
Linny-senpai: Exactly, just use seq 1 100. A 100-line job is done in one line. That's the power of sequence generation.

If you forget the $( ) in for i in $(seq ...) and write for i in seq 1 5, the loop iterates over the three literal strings seq, 1, and 5. The $( ) that replaces a command with its output is required.

5. How Do I Align the Digits (Zero Padding)?

Conclusion: Add -w to pad numbers with leading zeros to the widest value. file01, file02, ... file10 keep their digits aligned so the sort order stays correct.

Lina: When I listed test1.txt through test100.txt with ls, they came out in a weird order: test1, test10, test100, test2...
Linny-senpai: That's because the digit counts differ. Use -w (width) and it pads with zeros, like 001, 002, ... 100. The order holds even when sorted as text.
$ seq -w 1 10
01
02
03
04
05
06
07
08
09
10
Lina: Everything is two digits now!
Linny-senpai: The largest number (10 here) has two digits, so they all become two digits. Go up to 100 and they align to three digits (001-100). Now your filenames sort cleanly.

Combine it with file creation like this:

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

This creates log_001.txt through log_100.txt with aligned digits.

6. How Do I Change the Separator or Format?

Conclusion: Use -s to change the separator from newline to a comma, space, etc. Use -f to set a printf-style format.

Lina: What if I want "1,2,3,4,5" in a row instead of a column?
Linny-senpai: Use -s (separator). -s , joins them with commas.
$ seq -s , 1 5
1,2,3,4,5
Lina: Now it's one line. Can I use a space separator too?
Linny-senpai: -s " " gives spaces. And -f lets you add a prefix or set the digit width with a finer format.
$ seq -f "page-%02g" 1 3
page-01
page-02
page-03

In -f, %g represents a number. The 02 in %02g means "2 digits, zero-padded." For zero padding alone, -w from the previous section is simpler, but -f lets you add prefixes and decimal places freely.

7. How Is It Different from bash's {1..10}?

Conclusion: bash also has {1..10} for sequences. For fixed values, {1..10} is faster. When the range comes from a variable, use seq.

Lina: I once saw echo {1..5} print a sequence. How is that different from seq?
Linny-senpai: Good eye. {1..5} is bash "brace expansion," which is faster than seq. But it has a weakness: it does not expand when you use a variable.
$ echo {1..5}
1 2 3 4 5
$ n=5
$ echo {1..$n}
{1..5}
Lina: Huh, {1..$n} did not become a sequence; it printed the literal text.
Linny-senpai: Right. Brace expansion does not work with variables. But seq 1 $n honors the variable. That's why seq shines when the loop count comes from a variable.
$ n=5
$ seq 1 $n
1
2
3
4
5

for i in $(seq 1 $n) expands the whole sequence into memory for large numbers. For tens of thousands to millions of iterations, the arithmetic loop for ((i=1; i<=n; i++)) is more efficient. For the everyday range of tens to thousands, seq is fine.

Mini Challenge (click to open)

Create 12 files from report_01.txt to report_12.txt in bulk, with two-digit zero padding.

Hint: Align digits with -w and combine a for loop with touch. for i in $(seq -w 1 12); do touch "report_${i}.txt"; done

8. Common Pitfalls and Fixes

Conclusion: Most trouble comes from three things: misreading the argument count, forgetting $( ), and broken sort order from missing zero padding.

Symptom Cause Fix
A different range than expected Misunderstood the argument count Check the order seq START STEP END
Loop iterates over seq 1 5 text Forgot the $( ) Write for i in $(seq 1 5)
Files sort in a broken order No zero padding Align digits with seq -w
{1..$n} is not a sequence Brace expansion ignores variables Use seq 1 $n
Output is a column, not a row Default separator is a newline Change it with -s , or -s " "

What not to do

  • Expanding a huge range (millions) all at once with $(seq ...) and exhausting memory
  • Creating numbered files without zero padding and struggling with sort order later

Summary / Next Reading