seq 属于 通用工具命令(Utility Command),主要用于在脚本和命令行中生成一个数字序列。它不是核心系统管理命令,但它作为一种管道(pipe)和循环的辅助工具,在自动化和批处理任务中非常常见。由于需要启动一个新进程,在处理大量数字时,它的执行速度比大括号扩展慢,大括号扩展是 Bash Shell 的内置功能。它在 Shell 内部直接完成,不需要启动任何外部程序。

seq

一、基本语法与三种调用形式

1
2
3
seq [OPTION]... LAST
seq [OPTION]... FIRST LAST
seq [OPTION]... FIRST INCREMENT LAST
  • FIRST/INCREMENT/LAST 都可为整数或浮点数;步长可为负(降序)。
  • seq 包含端点:从 FIRST 开始,按步长累加/累减,只要不超过 LAST 的方向边界就输出。

二、常用参数

  • -s, --separator=STRING:自定义分隔符(默认换行)。最后仍有一个换行结尾。
  • -w, --equal-width:按最终最大宽度左侧零填充(保留符号),确保等宽。
  • -f, --format=FORMATprintf 风格的浮点格式(默认 %g)。常用如 %.0f%03.0f%.2f 等。
  • --help / --version:帮助/版本信息。

实务建议:

  • 需要对齐/零填充优先用 -w;若要更复杂的格式(前后缀、固定小数位)用 -f
  • 浮点用 -f 明确精度,避免 %g 触发科学计数法。

三、输出规则与坑点

  1. 方向与包含

    • seq 1 51 2 3 4 5
    • seq 5 -1 15 4 3 2 1
    • 当 FIRST 与 LAST 不满足步长方向(例如 seq 1 -1 10),输出为空。
  2. 浮点累积误差

    • seq 0 0.1 1 可能出现 0.30000000000004 类似情况或“不到/超过”终点一位。
    • 对策:-f '%.1f' 显式格式化,或在生成后用 awk/bc 处理。
  3. 本地化

    • 输出受 LC_NUMERIC 影响(小数点符号)。在脚本里建议固定 LC_ALL=C 保持可预期。

    • 在不同的语言环境下,小数点符号可能不同:

      • C 语言环境(和多数英语环境)使用. 作为小数点。
      • 许多欧洲语言环境(如德语、法语)使用逗号 , 作为小数点。

      这会导致你的脚本在不同系统上运行结果不一致,甚至报错。例如,如果你的脚本期望 seq 输出 0.5,但在使用逗号的系统上得到了 0,5,那么后续的数值计算或比较就会出错。通过在脚本中明确设置 LC_ALL=C,可以强制将所有的本地化设置重置为标准的 C 语言环境,从而保证 seq 等命令的行为是可预测的。

  4. 性能

    • 几百万行以上才需要考虑性能;一般运维脚本直接用 seq 足够快。并发任务用 xargs -P/GNU parallel。

四、参数与格式化实例(从基础到进阶)

1)自定义分隔符

1
2
3
# 用逗号分隔
seq -s, 1 5
# 输出:1,2,3,4,5

2)等宽零填充

1
2
seq -w 1 12
# 输出:01 02 ... 12 (按最大宽度填充)

3)printf 风格格式化(-f)

1
2
3
4
5
6
7
8
9
10
# 固定两位小数
seq -f '%.2f' 1 0.5 2
# 输出:1.00 1.50 2.00

# 三位零填充 + 自定义前缀
seq -f 'srv-%03.0f' 1 15
# 输出:srv-001 ... srv-015

# 主机名列表,带域名
seq -f 'web%02.0f.prod.example.com' 1 24

4)负步长(降序)

1
2
seq 10 -2 0
# 输出:10 8 6 4 2 0

5)浮点序列(注意精度控制)

1
2
# 建议指定格式控制精度,避免科学计数/误差
LC_ALL=C seq -f '%.1f' 0 0.1 1

6)综合:分隔符 + 格式

1
2
3
# CPU 亲和性掩码序列(逗号分隔,零填充两位)
seq -f '%02.0f' -s, 0 15
# 输出:00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15

五、与花括号展开 {..}jot 的比较(实战取舍)

工具特点适用场景局限
Bash 花括号 {1..10..2}超快、语法简单、无需进程常量范围已知的循环、脚本内快速枚举只支持整数不能用变量{1..$n}无效);复杂格式不便
seq变量友好、支持浮点、格式化、分隔符、等宽运行时动态范围、格式控制、生成 CSV/列表大量输出会稍慢于花括号(但多数场景无感)
jot(BSD/macOS)功能强大,格式化灵活macOS/FreeBSD 常见,jot -w '%02d' - 1 10Linux 发行版多不预装

在 Linux 服务器脚本中:

  • 常量整数且追求极简:for i in {1..10}; do ...; done
  • 变量/浮点/格式控制:首选 seq
  • macOS 上也可用 jot,等价写法示范:jot -w '%02d' - 1 10

六、生产级用法案例

1)批量并发执行任务(多进程)

1
2
3
4
5
# 并发 4 个执行器处理 1..20 的任务
seq 1 20 | xargs -n1 -P4 -I{} sh -c '
echo "worker $$ handling job {}"
# 你的任务逻辑,比如 curl / 编译 / 压缩
'

2)按编号批量创建/删除文件

1
2
3
4
5
# 创建日志文件 log-001.log ... log-100.log
seq -f 'log-%03.0f.log' 1 100 | xargs -I{} touch {}

# 删除序号范围内的文件
seq -f 'log-%03.0f.log' 20 30 | xargs rm -f

3)生成 Nginx upstream 配置片段

1
2
3
4
# 生成 upstream server 列表,端口 8001~8016
seq 1 16 | awk '{printf " server 10.0.0.%d:80%02d;\n", $1, $1}'
seq 1 16 | xargs -I{} printf " server 10.0.0.%d:80%02d;\n" {} {}
# 配合 heredoc 组装进完整 nginx 配置

4)构造 SQL IN 列表(避免手写)

1
2
# 生成 (1,2,3,4,5)
echo "SELECT * FROM t WHERE id IN ($(seq -s, 1 5));"

5)Kubernetes/容器实例名批量生成

1
seq -f 'pod-%02.0f' 1 10 | xargs -I{} kubectl delete pod {}

6)生成时间片 / 批次号(浮点步长)

1
2
# 每 0.5 生成一个批次号:batch-0.0, 0.5, 1.0, ... 5.0
LC_ALL=C seq -f 'batch-%.1f' 0 0.5 5

7)IP 列表枚举(仅一段)

1
2
# 10.0.0.1 ~ 10.0.0.254
seq -f '10.0.0.%g' 1 254

多段 IP(如 10.0.{1..3}.{1..254})建议嵌套:外层花括号 + 内层 seq 或使用 awk 生成。

8)for 循环与稳健性

1
2
3
4
5
6
7
# 简短:整数常量
for i in {1..10}; do echo "$i"; done

# 变量范围:用 seq,并避免 IFS/空白问题
while IFS= read -r i; do
echo "do $i"
done < <(seq 1 "$N")

9)对齐报表

1
2
3
4
# 右对齐 5 宽度(零填充)
seq -f '%05.0f' 1 15
# 或等宽(按最大位数自动):
seq -w 1 15

10)生成系统服务实例化配置

1
2
# systemd template 服务多实例启动
seq -f 'svc@%02.0f' 1 8 | xargs -n1 systemctl start

七、常见陷阱与最佳实践

  1. 浮点精度
    • 坑:seq 0 0.1 1 可能多出 1.1,或缺少 1.0
    • 方案:LC_ALL=C seq -f '%.1f' 0 0.1 1 | sed 's/,/./g'(必要时统一小数点),或改用 awk 'BEGIN{for(i=0;i<=1;i+=0.1) printf "%.1f\n", i}'
  2. 变量与花括号
    • {1..$n} 不会按预期展开;需要 seq 1 "$n"
  3. 零填充一致性
    • -w 更“智能”(自动匹配末位宽度)。
    • 如你需要固定位数包含自定义前后缀,优先 -f '%03.0f'
  4. 分隔符与尾随换行
    • -s 仍会在结尾输出一个换行;若不想要,可 tr -d '\n'printf '%s' "$(seq -s, 1 5)"
  5. LC_NUMERIC 导致的小数点符
    • 脚本里把 LC_ALL=C 放在命令前,确保 . 作为小数点,避免跨区服/容器里出现 ,

八、进阶模式:用 -f 一步生成“模板化”文本

1
2
3
4
5
# 直接生成配置行(每行一个 key=value)
seq -f 'worker.rack%02.0f=enabled' 1 12

# 生成 JSON 片段(逗号分隔)
printf '[%s]\n' "$(seq -f '{"id":%.0f}' -s, 1 5)"

九、BSD/macOS 的 jot 等价(以备跨平台)

1
2
3
4
# Linux seq
seq -f 'srv-%03.0f' 1 5
# macOS jot
jot -w 'srv-%03d' 5 1 5 # count=5, start=1, end=5

Bash 大括号扩展

Bash 大括号扩展(brace expansion),这是 Bash 中非常强大的一个特性。

一、基本概念

大括号扩展(Brace Expansion)是在 Bash(以及 zsh 等部分 shell)中预处理的功能。
它在命令执行前就会展开,不依赖文件系统。

语法:

1
2
3
{item1,item2,...}
{start..end}
{start..end..step}

二、基本用法

1. 逗号分隔形式

1
2
echo {a,b,c}
# 输出:a b c

可以嵌套:

1
2
echo {A,B}{1,2}
# 输出:A1 A2 B1 B2

2. 范围形式(整数/字符)

1
2
3
4
5
echo {1..5}
# 输出:1 2 3 4 5

echo {a..e}
# 输出:a b c d e

3. 指定步长

1
2
3
4
5
echo {1..10..2}
# 输出:1 3 5 7 9

echo {z..a..-2}
# 输出:z x v t r p n l j h f d b

三、常见应用场景

1. 批量创建文件/目录

1
2
3
4
5
mkdir project/{src,bin,docs,tests}
# 创建 src bin docs tests 四个目录

touch log_{2020..2023}.txt
# 创建 log_2020.txt log_2021.txt log_2022.txt log_2023.txt

2. 组合字符串

1
2
echo file{A,B}_{1..3}.txt
# 输出:fileA_1.txt fileA_2.txt fileA_3.txt fileB_1.txt fileB_2.txt fileB_3.txt

3. 多级嵌套

1
2
echo {red,green,blue}{1..2}
# 输出:red1 red2 green1 green2 blue1 blue2

4. 与循环结合

1
2
3
4
for i in {01..05}; do
echo "backup_$i.tar.gz"
done
# 输出:backup_01.tar.gz ... backup_05.tar.gz

⚠️ 注意:大括号展开 不支持变量
例如:

1
2
n=5
echo {1..$n} # ❌ 不会展开

这种情况就要用 seqfor i in $(seq 1 $n)

四、和 seq 的区别

特性Brace Expansionseq
执行时机预处理阶段(不执行命令就展开)运行时命令输出
是否支持变量❌ 不支持✅ 支持
支持浮点❌ 不支持✅ 支持
性能更快(内建)外部命令,稍慢
格式化❌ 不支持零填充/小数位✅ 支持 -f 格式化

五、进阶技巧

1. 零填充

bash 4+ 可以用零填充:

1
2
echo {01..10}
# 输出:01 02 03 04 05 06 07 08 09 10

2. 结合 cp / mv

1
2
cp file{1..3}.txt backup/
# 相当于 cp file1.txt file2.txt file3.txt backup/

3. 构造矩阵

1
2
echo {A..C}{1..3}
# 输出:A1 A2 A3 B1 B2 B3 C1 C2 C3

总结:

  • 大括号展开适合:固定范围、常量场景、快速写法。
  • seq适合:动态变量、浮点数、复杂格式化。