一、批量下载
脚本编写:
主要使用ChatGPT编写了应用代码
1.从源文件中读取需要的sra地址,并且记录到SRR_list.txt中
import csv
# 打开CSV文件并读取内容
with open('16s.csv', mode='r', encoding='utf-8') as csv_file:
csv_reader = csv.reader(csv_file)
next(csv_reader) # 跳过表头
# 打开TXT文件写入数据
with open('SRR_list.txt', mode='w', encoding='utf-8') as txt_file:
for row in csv_reader:
txt_file.write(row[1].strip() + '\n') # 将第二列内容写入TXT文件,每个数据占一行,且去除前后空格
2.使用GPT写linux中的shell脚本,一开始有很多错误,应该是某些看不到的格式问题,所以让GPT帮忙做了sra地址前后的空白符去除,并对下载失败的sra地址进行记录,haizu最终产生了以下的脚本
#!/bin/bash
# 检查 SRR_list.txt 文件是否存在
if [ ! -f SRR_list.txt ]; then
echo "Error: SRR_list.txt not found."
exit 1
fi
# 清空或创建失败日志文件
failed_log="failed_accessions.log"
> "$failed_log"
# 逐行读取 SRR_list.txt 文件中的数据
while IFS= read -r line
do
# 去除行内所有空格
trimmed_line=$(echo "$line" | tr -d '[:space:]')
# 检查读取数据的文件是否已存在
if ls "${trimmed_line}"* 1> /dev/null 2>&1; then
echo "Files for accession '${trimmed_line}' already exist. Skipping..."
continue
fi
# 执行 prefetch 命令
echo "Running prefetch for accession: ${trimmed_line}"
prefetch "${trimmed_line}"
# 检查 prefetch 命令的退出状态码
if [ $? -ne 0 ]; then
echo "Error: prefetch command failed for '${trimmed_line}'"
echo "${trimmed_line}" >> "$failed_log"
continue # 继续到下一行
fi
# 执行 fastq-dump 命令
echo "Running fastq-dump for accession: ${trimmed_line}"
fastq-dump --split-files "${trimmed_line}"
# 删除 prefetch 下载的文件夹
echo "Removing prefetch directory for accession: ${trimmed_line}"
rm -rf "${trimmed_line}"
done < SRR_list.txt
echo "Script finished. Check '$failed_log' for failed records."
二、提高速度
在linux当中开了一个客户端下载发现网络占用只占用了不到一半,而CPU和内存占用非常少,所以这整个批量下载过程的限速端明显是网络,因此就在脚本中加了一个分流功能,首先对下载的地址进行一个计数,然后根据对n取余来进行下载,这样做的好处是可以开n个客户端同时下载,那么就可以占满网络带宽从而提高整体下载速度,其实就是多线程的思想
这个是单个客户端的下载网络占用
以下是开了两个客户端的网络占用
明显空闲率更低了
以下是脚本,可以对里面的取余的数字进行更改,然后开多个客户端进行下载,通过更改counter % 2 == 0里面的2和0,就可以实现分流的作用,比如我这里是2就代表着我要开启两个客户端,0就代表这个客户端中是下载偶数的,再另一个客户端中就应该把0改成1,这样那个客户端只需要下载奇数的地址,这样就等于是下载速度翻倍了
#!/bin/bash
# 检查 SRR_list.txt 文件是否存在
if [ ! -f SRR_list.txt ]; then
echo "Error: SRR_list.txt not found."
exit 1
fi
# 清空或创建失败日志文件
failed_log="failed_accessions.log"
> "$failed_log"
# 初始化计数器
counter=0
# 逐行读取 SRR_list.txt 文件中的数据
while IFS= read -r line
do
# 增加计数器
counter=$((counter + 1))
# 检查计数器是否为偶数,如果是则跳过此循环
if (( counter % 2 != 0 )); then
echo "Skipping even-numbered accession: ${counter}"
continue
fi
# 去除行内所有空格
trimmed_line=$(echo "$line" | tr -d '[:space:]')
# 检查读取数据的文件是否已存在
if ls "${trimmed_line}"* 1> /dev/null 2>&1; then
echo "Files for accession '${trimmed_line}' already exist. Skipping..."
continue
fi
# 执行 prefetch 命令
echo "Running prefetch for accession: ${trimmed_line}"
prefetch "${trimmed_line}"
# 检查 prefetch 命令的退出状态码
if [ $? -ne 0 ]; then
echo "Error: prefetch command failed for '${trimmed_line}'"
echo "${trimmed_line}" >> "$failed_log"
continue # 继续到下一行
fi
# 执行 fastq-dump 命令
echo "Running fastq-dump for accession: ${trimmed_line}"
fastq-dump --split-files "${trimmed_line}"
# 删除 prefetch 下载的文件夹
echo "Removing prefetch directory for accession: ${trimmed_line}"
rm -rf "${trimmed_line}"
done < SRR_list.txt
echo "Script finished. Check '$failed_log' for failed records."