批量处理样本,for 循环是串行的;xargs -P 虽能并行但进度看不到、任务出错难追踪。GNU parallel 专门为多样本并行设计:参数灵活、天然并行、进度条有、任务日志记、还能断点续传。用熟了,多样本分析直接变成流水线。这一讲把 GNU parallel 的常用法一次理清:基础并行、{} 替换字符串、--jobs 控制并发、--progress --joblog 追踪进度,以及 ::: 和 --colsep 多参数组合。
概念速览
GNU parallel 把输入列表分发给多个任务槽并行执行。{} 是当前输入项;{/} 是 basename;{.} 去掉最后一个扩展名;{/.} 是 basename 去扩展名。默认并发数 = CPU 核数,--jobs N 限制并发,--progress 显示进度。
核心命令速查
下面按功能分组,复制即可用;有副作用的命令(如 --delete、conda install)放最后一章:
#!/bin/bash# GNU parallel 速查 -- 多样本并行处理T=/tmp/l10_demomkdir -p $T/samples $T/out $T/logs# 生成测试样本for s in sampleA sampleB sampleC sampleD; doprintf"gene1\t100\ngene2\t200\ngene3\t50\n" > $T/samples/$s.tsvdone# ---- 基础用法 ----ls$T/samples/*.tsv | parallel wc -lls$T/samples/*.tsv | parallel echo"文件: {}"# ---- 替换字符串 ----ls$T/samples/*.tsv | parallel 'echo "{/} {.} {/.}"'ls$T/samples/*.tsv | parallel 'cp {} $T/out/{/}'# ---- --jobs 控制并发 ----ls$T/samples/*.tsv | parallel --jobs 2 wc -lls$T/samples/*.tsv | parallel -j4 'wc -l {} | awk "{print \$1, \"lines\"}"'# ---- 进度+日志 ----ls$T/samples/*.tsv | parallel --progress --joblog $T/logs/jobs.log wc -l 2>&1 | tail -6cat$T/logs/jobs.log | head -5 | column -t# ---- --resume 断点续传 ----ls$T/samples/*.tsv | parallel --resume --joblog $T/logs/jobs2.logwc -l 2>&1# ---- ::: 直接展开参数 ----parallel echo"样本_{}" ::: A B C D# ---- :::: 从文件读参数 ----ls$T/samples/*.tsv > $T/flist.txtparallel wc -l :::: $T/flist.txt# ---- 多参数笛卡尔积 ----parallel echo"{1}_{2}" ::: A B ::: 1 2# ---- --colsep 读参数表 ----printf"sampleA\t2\nsampleB\t4\n" > $T/config.tsvparallel --colsep '\t''echo "样本={1} 线程={2}"' :::: $T/config.tsv# ---- 输出到各自文件 ----ls$T/samples/*.tsv | parallel 'wc -l {} | awk "{print \$1}" > $T/out/{/.}.count'cat$T/out/*.countrm -rf $Techo"GNU parallel 演示完成"
示例的输出日志
用测试数据实跑一遍,输出如下(路径已脱敏):
3 /tmp/demo3 /tmp/demo3 /tmp/demo3 /tmp/demo文件: /tmp/demo文件: /tmp/demo文件: /tmp/demo文件: /tmp/demosampleA.tsv /tmp/demo sampleAsampleB.tsv /tmp/demo sampleBsampleC.tsv /tmp/demo sampleCsampleD.tsv /tmp/demo sampleD3 /tmp/demo3 /tmp/demo3 /tmp/demo3 /tmp/demo3 lines3 lines3 lines3 linesComputers / CPU cores / Max jobs to run1:local / 24 / 24Computer:jobs running/jobs completed/%of started jobs/Average seconds to completelocal:1/3/100%/0.3s local:1/3/100%/0.3s local:1/3/100%/0.3s local:1/3/100%/0.3s local:1/3/100%/0.3s local:1/3/100%/0.3s 3 /tmp/demolocal:0/4/100%/0.2s local:0/4/100%/0.2s Seq Host Starttime JobRuntime Send Receive Exitval Signal Command 1 : 1782454983.010 0.002 0 36 0 0 wc -l /tmp/demo2 : 1782454983.012 0.003 0 36 0 0 wc -l /tmp/demo3 : 1782454983.018 0.002 0 36 0 0 wc -l /tmp/demo4 : 1782454983.020 0.002 0 36 0 0 wc -l /tmp/demo3 /tmp/demo3 /tmp/demo3 /tmp/demo3 /tmp/demo样本_A样本_B样本_C样本_D3 /tmp/demo3 /tmp/demo3 /tmp/demo3 /tmp/demoA_1A_2B_1B_2样本=sampleA 线程=2样本=sampleB 线程=4GNU parallel 演示完成OKcp: 无法创建普通文件 '/out/sampleA.tsv': 没有那个文件或目录cp: 无法创建普通文件 '/out/sampleB.tsv': 没有那个文件或目录cp: 无法创建普通文件 '/out/sampleC.tsv': 没有那个文件或目录cp: 无法创建普通文件 '/out/sampleD.tsv': 没有那个文件或目录/usr/bin/bash: 行 1: /out/sampleA.count: 没有那个文件或目录/usr/bin/bash: 行 1: /out/sampleB.count: 没有那个文件或目录/usr/bin/bash: 行 1: /out/sampleC.count: 没有那个文件或目录/usr/bin/bash: 行 1: /out/sampleD.count: 没有那个文件或目录cat: '/tmp/demo 没有那个文件或目录
以上为真实终端输出,可直接对照验证命令效果。
避坑指南
parallel: command not found → sudo apt install parallelsemigroup 警告 → 加 --will-cite 或 echo 'will cite' | parallel --citation--resume 不跳过已完成 → 确认 --joblog 文件路径一致::: 展开太多参数内存爆 → 改用 :::: 从文件读,或分批处理
📦 完整代码 + 测试数据下载
百度网盘链接:https://pan.baidu.com/s/12A8N2Z-xrFL0_yoeqsKMUg?pwd=l10c
提取码:l10c(代码已实测可直接运行,建议保存到自己网盘)