shuf 是什么
shuf 是 GNU coreutils 提供的随机重排工具:把输入的行随机洗牌,或按数量随机抽样,也能直接生成随机整数。它用系统熵源取种,质量足够日常使用,但官方并不承诺密码学安全。它解决的是「抽样」和「打乱顺序」这两件事——日志抽检、测试样本准备、随机选机器、给任务加随机抖动,都是一行命令的事。相比 sort -R,shuf 语义更明确、抽样场景更省内存。
基本信息
| 适用平台 | GNU/Linux(coreutils);macOS 需安装 coreutils 后叫 gshuf |
|---|---|
| 语法 | shuf [选项] [文件] |
| 常用选项 | -n 取 N 行 -e 参数列表 -i 整数范围 -r 允许重复 |
| 默认行为 | 把整个输入读入内存后随机打乱所有行 |
| 资源特征 | 内存占用与输入规模成正比 |
| 随机源 | 系统熵源,非密码学强度 |
典型使用场景
- 从访问日志里随机抽几百条做人工抽检,避免只看最新记录带来的偏差。
- 给压测或模型训练准备随机样本,例如从百万行 CSV 里抽一万行。
- 给人员名单随机排序或随机分组,用于演练排班、值班轮值与抽样审计。
- 生成随机端口或随机等待秒数,为批量脚本加抖动,避免同时打同一个接口。
- 从节点列表里随机挑一台执行巡检,把负载分散到不同机器。
常用写法
常用写法
shuf access.log | head -100 # 打乱后取前 100 行做抽样
shuf -n 1000 big.csv > sample.csv # 随机抽 1000 行(推荐写法)
shuf -i 1-100 -n 5 # 在 1 到 100 之间随机取 5 个整数
shuf -e web1 web2 web3 -n 1 # 随机挑一台机器
shuf -rn 10 -i 2000-65000 # 允许重复,生成 10 个随机端口
seq 1 30 | shuf -n 1 # 管道输入同样适用
shuf --random-source=/dev/zero f # 用固定随机源得到可复现结果
shuf all.txt -o all.txt # 原地打乱(先整读再写回)关键选项对照
| 选项 | 作用 | 使用要点 |
|---|---|---|
| -n N | 取 N 行 | 最常用,比打乱后 head 更省内存也更准确 |
| -e | 把参数当作输入行 | 适合少量候选项里随机挑选 |
| -i LO-HI | 生成整数范围 | 可配合 -n 直接抽样,免去先 seq |
| -r | 允许重复 | 严格随机数场景使用,默认不重复 |
| --random-source | 指定随机源文件 | 需要可复现结果时使用 |
| -o 文件 | 输出到文件 | 可原地覆盖,代价是要整读入内存 |
shuf 会把全部输入读进内存再洗牌,几个 GB 的日志直接用会吃掉等量内存。超大文件抽样改用 awk 的蓄水池写法(如 awk 'BEGIN{srand()}{if(rand()<0.001)print}'),代价是样本不是严格等概率,做统计口径说明时要讲清楚。
需要密码学强度的随机值(密钥、会话令牌、盐值)不要用 shuf,用 openssl rand -hex 32 或直接读 /dev/urandom。shuf 适合抽检、排班、抖动这类对不可预测性要求不高的场景。
想让抽检结果可复现(例如让同事复核同一批样本),用 --random-source 指定一个固定文件;否则每次结果不同,讨论样本时必须连同抽样清单一起传递。