为何Bash循环无法正确拼接fastq.gz文件?
拼接fastq.gz文件的循环执行失败问题
场景说明
当前目录下存在以下文件:
AB124661.lane3.R1.fastq.gz AB124661.lane4.R1.fastq.gz AB124661.lane3.R2.fastq.gz AB124661.lane4.R2.fastq.gz
需要执行的目标操作是将同样本同方向的lane文件拼接:
cat AB124661.lane3.R1.fastq.gz AB124661.lane4.R1.fastq.gz > AB124661.R1.fastq.gz cat AB124661.lane3.R2.fastq.gz AB124661.lane4.R2.fastq.gz > AB124661.R2.fastq.gz
尝试的操作及问题
- 生成存储样本ID的文件:
ls -1 R1.gz | awk -F '.' '{print $1}' | sort | uniq > ID
- 执行以下循环:
for i in `cat ./ID`; do cat $i\.lane3.R1.fastq.gz $i\.lane4.R1.fastq.gz \> out/$i\.R1.fastq.gz; done for i in `cat ./ID`; do cat $i\.lane3.R2.fastq.gz $i\.lane4.R2.fastq.gz \> out/$i\.R2.fastq.gz; done
循环执行后生成的目标文件为空,已确认:
- ID文件存在于当前目录
- 使用echo测试时,输出的cat命令格式看似正确
错误原因及修正方案
核心错误点
- 重定向符号被错误转义:循环中的
\>是多余操作,转义后shell会将>当作普通字符处理,导致cat的输出不会写入目标文件,而是直接打印到终端,同时会尝试读取不存在的out/$i.R1.fastq.gz,最终生成空文件。 - 可能缺少目标目录:如果
out目录不存在,重定向操作会直接失败,无法生成文件。 - 变量引用未加引号:虽然当前场景无空格问题,但未加引号的变量在遇到特殊字符或空格时会出现拆分错误,属于不规范写法。
修正后的命令
首先确保输出目录存在:
mkdir -p out
然后用更可靠的while read循环执行拼接:
while read i; do # 跳过空行 [ -z "$i" ] && continue cat "${i}.lane3.R1.fastq.gz" "${i}.lane4.R1.fastq.gz" > "out/${i}.R1.fastq.gz" cat "${i}.lane3.R2.fastq.gz" "${i}.lane4.R2.fastq.gz" > "out/${i}.R2.fastq.gz" done < ID
额外优化
如果需要一次性处理所有样本,也可以不用提前生成ID文件,直接通过文件名提取样本ID完成拼接(自动匹配所有lane编号):
mkdir -p out for r in R1 R2; do for i in $(ls *lane*.${r}.fastq.gz | awk -F '.' '{print $1}' | sort -u); do cat "${i}.lane"*.${r}.fastq.gz > "out/${i}.${r}.fastq.gz" done done
内容的提问来源于stack exchange,提问作者Avamys
相关产品推荐
相关产品推荐

