测序公司发回来的数据,文件名往往乱得头疼:有的带空格、有的后缀不统一、有的样本号没补零排序全乱。一个个手动改,几十个样本能改到怀疑人生,还容易把 R1/R2 配对改错,等跑到比对那一步报错才回头查,又得从头重来。这些活儿用几行 bash 就能批量搞定,而且全是 shell 内置语法,不依赖任何额外工具。这一讲把批量重命名的常用招式一次理清:后缀处理、字符替换、加前缀、删字段、重编号,照着改改就能套到自己的数据上。
为什么别手动改
几十上百个样本手动改名,慢不说,一旦改错一个 R1/R2 配对,下游比对就全错,还很难发现。批量脚本一次处理、规则统一,可靠得多。动手前先用 echo 预演一遍最稳。
核心命令速查
下面按「后缀 / 字符替换 / 加前缀 / 删字段 / 重编号 / 预演」分组,用前先 cd 到数据目录:
#!/bin/bash# 批量重命名常用招式速查,按需复制(先 cd 到数据目录再用)# ---- 后缀处理 ----for f in *.fq.gz; domv -- "$f""${f%.fq.gz}.fastq.gz"; done# 改后缀for f in *.fastq; domv -- "$f""$f.gz"; done# 加后缀for f in *.tmp; domv -- "$f""${f%.tmp}"; done# 去后缀# ---- 字符替换 ----for f in *\ *; domv -- "$f""${f// /_}"; done# 空格转下划线for f in *-*; domv -- "$f""${f//-/_}"; done# 连字符转下划线for f in *; domv -- "$f""${f,,}"; done# 文件名转小写# ---- 加前缀 / 标记 ----for f in *.fastq.gz; domv -- "$f""P01_$f"; done# 统一加项目前缀for f in *.bam; domv -- "$f""${f%.bam}.sorted.bam"; done# 加状态标记# ---- 删多余字段 ----for f in *_L001_*; domv -- "$f""${f/_L001/}"; done# 删中间字段for f in Sample_*; domv -- "$f""${f#Sample_}"; done# 删开头字段for f in *_001.*; domv -- "$f""${f/_001/}"; done# 删 Illumina 的 _001# ---- 重新编号 / 补零 ----i=1; for f in *.fastq.gz; domv -- "$f""$(printf 'S%02d.fastq.gz' "$i")"; i=$((i+1)); done# 补零重编号# ---- 其他常见 ----for f in *.sam; domv -- "$f""${f%.sam}.bam"; done# 改扩展名 sam->bamfor f in *.JPG; domv -- "$f""${f%.JPG}.jpg"; done# 大写后缀转小写for f in run1_*; domv -- "$f""batch1_${f#run1_}"; done# 整体换前缀# ---- 安全:先预演 ----for f in *.fq.gz; doechomv"$f""${f%.fq.gz}.fastq.gz"; done# 把 mv 换成 echo 只打印ls *.fastq.gz | wc -l # 数一下文件个数
mv -- 的 -- 防文件名以 - 开头被当参数;${f%.x} 砍后缀、${f// /_} 全局替换、${f,,} 转小写都是 bash 内置。
示例的输出日志
造几个乱名字的假文件,跑几个代表招式看效果:
--- 重命名前 ---ctrl_R1.fq.gzctrl_R2.fq.gzSample_case_001.fastq.gztreat 1_R1.fq.gz--- 重命名后 ---ctrl_R1.fastq.gzctrl_R2.fastq.gzSample_case.fastq.gztreat_1_R1.fastq.gzOK
.fq.gz 统一成 .fastq.gz、带空格的变下划线、_001 也删掉了——批量、零手工。
扩展:rename 与 find
复杂正则用 rename 更省事,要递归处理子目录就用 find:
# rename 是 perl 版(Ubuntu: sudo apt install rename)rename 's/_001//' *.fastq.gz # 正则删片段rename -n 's/\.fq\.gz$/.fastq.gz/' *.fq.gz # -n 只预演不执行# find 递归改子目录里的文件find . -name "*.fq.gz" -exec sh -c 'mv "$0" "${0%.fq.gz}.fastq.gz"' {} \;
rename 适合复杂正则、find 适合递归子目录;动手前都先用 -n 或 echo 预演。
避坑指南
- 改错没法撤 → 先 echo 预演,或先
cp -r 备份 - rename 行为不一致 → Ubuntu 是 perl 版、CentOS 是 util-linux 版,语法不同
- 通配符没匹配到 → 加
[ -e "$f" ] || continue 跳过
📦 完整代码 + 测试数据下载
百度网盘链接:https://pan.baidu.com/s/1Jgga9oU4oAxhpiZEFo4rcQ?pwd=l03c
提取码:l03c(代码已实测可直接运行,建议保存到自己网盘)