basename命令处理多fastq.gz文件无法正确去除后缀求助
问题描述
主机目录下有四个fastq.gz文件,文件名如下:
A29_WES_S3_R1_001.fastq.gz A29_WES_S3_R2_001.fastq.gz A30_WES_S1_R1_001.fastq.gz A30_WES_S1_R2_001.fastq.gz
需要获取去除.fastq.gz后缀的文件名,预期输出:
A29_WES_S3_R1_001 A29_WES_S3_R2_001 A30_WES_S1_R1_001 A30_WES_S1_R2_001
编写的bash脚本如下:
#!/bin/bash FILES1=(*R1_001.fastq.gz) FILES2=(*R2_001.fastq.gz) read1="${FILES1[@]}" read2="${FILES2[@]}" Ffile=$read1 Ffileprevix=$(basename "$Ffile" .fastq.gz) Mfile=$read2 Mfileprevix=$(basename "$Mfile" .fastq.gz) echo $Ffileprevix echo $Mfileprevix exit;
执行后仅最后一个文件的后缀被正确去除,实际输出:
A29_WES_S3_R1_001.fastq.gz A30_WES_S1_R1_001 A29_WES_S3_R2_001.fastq.gz A30_WES_S1_R2_001
尝试添加basename -a参数无效,循环也没成功,需要解决这个问题。
解决方法
问题根源是把数组元素拼接成单个字符串后传给basename,basename只会处理最后一个匹配后缀的文件名,前面的元素会原样输出。以下是几种可行的解决方式:
方案1:循环遍历数组逐个处理
直接遍历每个数组元素,用basename单独处理:
#!/bin/bash FILES1=(*R1_001.fastq.gz) FILES2=(*R2_001.fastq.gz) # 处理所有R1文件 for file in "${FILES1[@]}"; do echo "$(basename "$file" .fastq.gz)" done # 处理所有R2文件 for file in "${FILES2[@]}"; do echo "$(basename "$file" .fastq.gz)" done
方案2:用bash参数扩展替代basename
bash原生支持参数扩展去除后缀,无需调用外部命令,效率更高:
#!/bin/bash FILES1=(*R1_001.fastq.gz) FILES2=(*R2_001.fastq.gz) for file in "${FILES1[@]}" "${FILES2[@]}"; do echo "${file%.fastq.gz}" done
${file%.fastq.gz}表示从字符串末尾匹配.fastq.gz并删除,完全满足需求。
方案3:一次性处理所有目标文件
如果不需要区分R1和R2,可以直接匹配所有.fastq.gz文件:
#!/bin/bash for file in *.fastq.gz; do echo "${file%.fastq.gz}" done
内容的提问来源于stack exchange,提问作者Alireza
相关产品推荐
相关产品推荐

