如何将编号基因文件分类复制到递增编号文件夹中
问题描述
我有一批命名为gene_1.fa、gene_2.fa……gene_19500.fa的基因文件,需要将它们分类放入200、400、600……19600这些文件夹中用于下游分析。原本的实现思路需要写大量elif判断,操作十分繁琐:
for file in "${files[@]}"; do base_name=$(basename "$file") gene_number=$(echo "$base_name" | cut -d'_' -f2 | cut -d'.' -f1) to_path= (path to folder containing 200, 400, ... 19600 folders) #if it's gene_200.fa, 400.fa etc. copy into that dir if (( $gene_number%200 == 0)); then cp file $to_path/$gene_number/$file elif (( $gene_number < 200 )); then cp file $to_path/200/$file elif (( $gene_number > 19400)); then cp file $to_path/19600/$file # the endless pain of 200-400, 400-600, 600-800 ... 19200-19400 elif (( $gene_number > 200 && $gene_number < 400)); then cp file $to_path/19600/$file elif ....
我需要更简便的实现方法,且确保单个文件不会被复制到多个文件夹中。
简化实现方法
可以通过算术运算直接计算出每个文件对应的目标文件夹,避免大量条件判断,脚本如下:
# 替换为存放200、400等文件夹的根路径 to_path="/your/target/root/path" # 遍历所有基因文件 for file in gene_*.fa; do # 提取文件名中的基因编号 gene_number=$(echo "$file" | sed -E 's/gene_([0-9]+)\.fa/\1/') # 计算目标文件夹 if (( gene_number <= 200 )); then target_dir="200" elif (( gene_number >= 19401 )); then target_dir="19600" else # 通过向上取整计算对应区间的文件夹名 target_dir=$(( ((gene_number + 199) / 200) * 200 )) fi # 确保目标文件夹存在(不存在则自动创建) mkdir -p "$to_path/$target_dir" # 复制文件到目标文件夹 cp "$file" "$to_path/$target_dir/" done
关键说明
- 基因编号提取:用
sed正则表达式一次性从文件名中提取数字,比多次cut更简洁高效。 - 目标文件夹计算:
- 编号≤200直接归入
200文件夹,编号≥19401直接归入19600文件夹; - 中间编号通过
((gene_number + 199) / 200) * 200实现向上取整后乘以200,自动匹配对应的区间文件夹(比如201→400,401→600,以此类推)。
- 编号≤200直接归入
- 避免重复复制:每个文件只会根据编号计算出唯一的目标文件夹,不会出现一个文件被复制到多个文件夹的情况。
- 容错处理:
mkdir -p确保目标文件夹存在,即使之前未创建也不会报错。
内容的提问来源于stack exchange,提问作者Amanda
相关产品推荐
相关产品推荐

