Ubuntu/Linux下按可变模式批量重命名文件求助
没问题,针对你这种需要移除可变中间段的批量重命名需求,我给你几个实用的方案,都是经过验证的:
方案一:原生Bash循环(无需额外工具)
这个方案利用Bash自带的参数扩展功能,完全不需要安装其他工具,适合所有类Unix系统。核心思路是提取文件名的前缀(第一个下划线之前的部分),再提取从_R开始的后缀部分,最后把两者拼接起来。
先执行测试命令(只输出要执行的重命名操作,不会实际修改文件):
for file in *.fastq.gz; do echo mv "${file}" "${file%%_*}_R${file#*_R}" done
如果输出的重命名逻辑符合你的预期,再去掉echo执行实际重命名:
for file in *.fastq.gz; do mv "${file}" "${file%%_*}_R${file#*_R}" done
逻辑解释:
${file%%_*}:提取文件名中第一个下划线之前的内容(比如1B、97C)${file#*_R}:提取文件名中从_R之后的所有内容(比如1_001.fastq.gz)- 拼接后就得到了
1B_R1_001.fastq.gz这类目标文件名
方案二:Perl版rename工具(简洁高效)
如果你的系统是Ubuntu/Debian这类默认使用Perl版rename的发行版,用正则表达式可以一步搞定,非常简洁。
先执行测试(-n参数只预览操作,不实际修改):
rename -n 's/^([^_]+)_.*(_R[12]_001\.fastq\.gz)$/$1$2/' *.fastq.gz
确认预览结果正确后,去掉-n执行实际重命名:
rename 's/^([^_]+)_.*(_R[12]_001\.fastq\.gz)$/$1$2/' *.fastq.gz
正则解释:
^([^_]+):捕获开头到第一个下划线的前缀(分组1)_.*:匹配要删除的可变中间段(_R[12]_001\.fastq\.gz)$:捕获结尾的固定后缀(分组2,匹配R1/R2)$1$2:将两个捕获分组拼接,得到目标文件名
如果你的系统是RHEL/CentOS这类使用util-linux版rename的发行版,语法和Bash循环类似,直接用这个命令即可:
# 测试 for file in *.fastq.gz; do echo rename "${file}" "${file%%_*}_R${file#*_R}" done # 实际执行 for file in *.fastq.gz; do rename "${file}" "${file%%_*}_R${file#*_R}" done
方案三:结合sed生成重命名命令
如果你习惯用sed处理字符串,可以先生成所有mv命令,检查无误后再执行:
# 生成命令并预览 ls *.fastq.gz | sed -E 's/(^[^_]+)_.*(_R[12]_001\.fastq\.gz)$/mv "&" "\1\2"/'
确认输出的命令正确后,通过管道传给Bash执行:
ls *.fastq.gz | sed -E 's/(^[^_]+)_.*(_R[12]_001\.fastq\.gz)$/mv "&" "\1\2"/' | bash
内容的提问来源于stack exchange,提问作者Deni Galinac Ribičić
相关产品推荐
相关产品推荐

