About the seq Command
The seq command generates sequences of numbers, printing them to standard output. It's a simple but incredibly useful tool for creating numeric sequences in shell scripts, loops, data generation, and testing. Seq can generate sequences with custom increments, formatting, and separators, making it versatile for various automation tasks.
Why it's useful: While bash has built-in range syntax like {1..10}, seq offers more flexibility with floating-point numbers, custom formatting (padding, decimal places), and dynamic ranges from variables. It's particularly valuable in scripts where you need precise control over number generation or when working with decimal values.
Common applications: Loop counters, generating test data, creating numbered filenames, batch processing, parallel job control, countdown timers, and mathematical sequence generation.
Detailed Examples
1Basic Sequence Generation
Generate simple numeric sequences with different syntaxes.
seq LAST generates from 1 to LAST. (2) seq FIRST LAST generates from FIRST to LAST. (3) seq FIRST INCREMENT LAST (see example 2). By default, seq prints one number per line, making it perfect for piping to other commands or using in loops. The sequences are inclusive - both FIRST and LAST are included in the output. Default behavior: When you specify only one number, seq starts at 1. When you specify two numbers, seq increments by 1. Each number is printed on its own line, which is ideal for shell processing where each line is treated as a separate item.
seq 5 > numbers.txt or pipe it: seq 5 | xargs echo2Custom Increment (Step)
Generate sequences with custom increments, including negative and decimal values.
seq FIRST INCREMENT LAST allows custom step values. First example: Count from 0 to 20 in steps of 5 (multiples of 5). Second example: Countdown from 10 to 0 in steps of -2 (negative increment for decreasing sequences). Third example: Decimal increments work perfectly - count from 0 to 2.5 in steps of 0.5. Important behavior: Seq stops when the next value would exceed LAST (or go below LAST for negative increments). If LAST isn't exactly reachable (e.g., seq 1 2 10 can't hit 10 exactly), seq stops at the last valid value (9 in this case). Floating-point arithmetic is supported, making seq more flexible than bash's brace expansion which only handles integers.
seq 60 -1 0 for a 60-second countdown timer.{1..10} doesn't support decimals or variables, but seq does: seq 1 0.1 2 works perfectly.3Custom Separator
Change the output separator from newline to any string.
-s (separator) option changes what appears between numbers. Default is newline, but you can use any string. First example: Space-separated output, all on one line. Second example: Comma-space separator for CSV-style output. Third example: Tab separator using $'\t' (ANSI-C quoting in bash). Fourth example: Pipe separator. Practical uses: Creating CSV data (-s ','), formatting for display (-s ', '), generating arrays for other languages, or creating URLs with dashes. The separator only appears between values, not before the first or after the last value.
Creating CSV Data
array=($(seq -s ' ' 1 10)) creates a bash array.4Equal Width with Leading Zeros
Pad numbers with leading zeros for consistent width.
-w (equal-width) option pads numbers with leading zeros so all output has the same width. Seq determines the width based on the widest number in the sequence (LAST or FIRST, whichever is wider). First example (no -w): Numbers 8-12 have varying widths (1 or 2 digits). Second example (with -w): All numbers are 2 digits wide, with 8 and 9 padded as 08 and 09. Third example: Generating 001-100, all 3 digits wide. Why this matters: Equal-width numbers sort correctly as strings (important for filenames), create aligned output in tables, and work better with systems that expect fixed-width fields. Without padding, string sorting gives "1, 10, 11, 2, 3..." instead of "1, 2, 3, 10, 11...".
Creating Numbered Filenames
5Printf-Style Formatting
Use custom format strings for precise control over output.
-f (format) option uses printf-style format strings where %g is replaced by each number. Format specifiers: %g = general number format (default). %03g = pad to 3 digits with zeros. %f = floating-point. %.2f = 2 decimal places. %e = scientific notation. First example: Adds prefix text to each number. Second example: Creates filenames with zero-padded numbers (alternative to -w). Third example: Complex formatting with both padding and decimal places. Fourth example: Zero-padding to 4 digits. This is more powerful than -w because you can add text before and after the number, control decimal places, and use other printf features.
6Using seq in For Loops
Common pattern: using seq to control loop iterations.
$(seq 1 5) expands to "1 2 3 4 5" which the for loop iterates over. Second example: Countdown using negative increment. Each iteration, $i takes the next value from the sequence. Alternative syntax: You could use bash's C-style for loop (for ((i=1; i<=5; i++))) or brace expansion (for i in {1..5}), but seq offers more flexibility with decimals, negative increments, and variable ranges. Important note: When the range comes from variables, you must use seq: for i in $(seq $start $end) works, but {$start..$end} doesn't (brace expansion happens before variable expansion).
end=10; for i in $(seq 1 $end); do echo $i; done works perfectly.for i in {1..10} brace expansion, but it's less flexible than seq (no decimals, no variables, no custom increments > 1).7Generating Test Data
Create test files, sample data, or mock records.
-w flag ensures log_01.txt through log_30.txt sort correctly. Second example: Generates 100 rows of CSV data with IDs, names, and random values. Seq provides the sequential IDs, while bash's RANDOM provides variety. Third example: Creates a nested directory structure for 6 years × 12 months = 72 directories. Uses nested seq loops with -w for month numbers (01-12). Why this matters: Testing often requires realistic volumes of data. Seq makes it trivial to generate thousands of files, records, or data points with sequential identifiers. Combined with shell scripting, you can create complex test scenarios quickly.
seq 1 1000 | xargs -I{} curl -s "https://api.example.com/user/{}" fetches data for users 1-1000.8Parallel Processing with Seq
Distribute work across parallel processes using sequences.
seq 1 10 100 to generate batch starting points: 1, 11, 21, 31... 91. Each batch processes 10 files (1-10, 11-20, etc.) in a subshell backgrounded with &. All batches run simultaneously (parallel processing). The wait command ensures the script doesn't exit until all background jobs complete. Real-world application: This pattern is valuable for CPU-bound tasks where you want to use multiple cores, or I/O-bound tasks where you can parallelize network requests. Advantages: Seq makes it easy to divide work into chunks. Variables let you adjust BATCH_SIZE dynamically. You can scale from 10 to 10,000 files just by changing one number. Alternative tools: GNU parallel or xargs -P can do similar things but with more features. Seq provides the basic building block for DIY parallelism.
sem (from GNU parallel package) or implement a simple semaphore to limit concurrent processes.9Mathematical Sequences and Calculations
Generate mathematical sequences and perform calculations.
10Advanced Formatting and Integration
Complex formatting and integration with other commands.
xargs curl or wget for batch downloads. Second example: Generate SQL INSERT statements for bulk data loading. Note the limitation: -f only accepts one format specifier, so both ID and username get the same number. For different values, use a loop. Third example: Mathematical expression generation - seq creates "1+2+3+4+5+6+7+8+9+10" which bc evaluates to 55. Fourth example: Process substitution with paste and column to create formatted tables. <(seq 1 5) generates numbers, <(seq -f "Item %g" 1 5) generates labels, paste combines them, column aligns columns. Integration power: Seq's simple output format makes it ideal for piping to other commands - every Unix tool that processes text can work with seq output.
seq 1 100 | xargs -I{} sh -c 'command_with_number_{}'Batch API Calls
Fetches items 1-100 with 10 parallel connections.
Complete Options Reference
| Option | Long Form | Description |
|---|---|---|
-f |
--format=FORMAT |
Use printf-style floating-point FORMAT (default: %g) |
-s |
--separator=STRING |
Use STRING to separate numbers (default: \n) |
-w |
--equal-width |
Equalize width by padding with leading zeros |
--help |
Display help message and exit | |
--version |
Output version information and exit |
seq vs. Bash Alternatives
| Feature | seq | Brace Expansion {1..10} | C-style for ((i=1;i<=10;i++)) |
|---|---|---|---|
| Decimal numbers | ✅ Yes | ❌ No | ❌ No (integers only) |
| Variable ranges | ✅ Yes: seq $start $end | ❌ No: {$a..$b} doesn't work | ✅ Yes |
| Custom formatting | ✅ Yes: -f, -w, -s | ❌ No | ❌ No |
| Negative increments | ✅ Yes | ✅ Yes: {10..1..-2} | ✅ Yes |
| Piping to commands | ✅ Easy | ⚠️ Needs echo or for loop | ⚠️ Needs explicit loop |
| Performance | ⚠️ External process | ✅ Built-in, fast | ✅ Built-in, fast |
| Portability | ⚠️ Needs seq installed | ⚠️ Bash 3.0+ only | ⚠️ Bash 2.0+ only |
Best Practices
When and How to Use seq Effectively
- Use seq when you need:
- Decimal/floating-point sequences
- Custom formatting (padding, separators)
- Variable-based ranges that brace expansion can't handle
- To pipe sequences to other commands
- Precise control over output format
- Prefer alternatives when:
- Simple integer ranges with literal values: use {1..10}
- Complex loop conditions: use C-style for loops
- Performance is critical in tight loops
- Quoting and word splitting: Use quotes when assigning seq output:
numbers="$(seq 1 10)" - Large sequences: Be mindful of memory with huge sequences - seq 1 1000000 generates a million numbers
- Floating-point precision: Be aware of floating-point rounding -
seq 0 0.1 1might not hit 1.0 exactly - Test your ranges: Always test with small ranges first, then scale up
- Use -w for filenames: When generating numbered files, -w ensures proper sorting
- Combine with other tools: Seq is most powerful when piped to xargs, parallel, awk, etc.
Common Use Cases
Batch File Processing
Resize image to 1%, 2%, ... 100% of original size.
Database Seeding
Insert 1000 test users into database.
Waiting/Retry Logic
Retry with exponential backoff (2, 4, 6, 8, 10 seconds).
Log Rotation Simulation
Rotate logs: app.log.5→6, 4→5, 3→4, 2→3, 1→2, app.log→1
Related Commands
- yes: Repeat a string infinitely (or until killed)
- jot: BSD alternative to seq (different syntax)
- shuf: Generate random permutations (can shuffle seq output)
- bc: Arbitrary precision calculator for math on sequences
- awk: Can generate sequences: awk 'BEGIN{for(i=1;i<=10;i++)print i}'
- perl/python: More powerful sequence/range generation for complex needs
- xargs: Build and execute commands from standard input (perfect with seq)
- parallel: GNU parallel for sophisticated parallel processing