Bash 使用 gzip 和 bcftools 的脚本 运行 大文件内存不足
Bash script using gzip and bcftools running out of memory with large files
此 bash 脚本旨在成为处理压缩 .vcf 文件的管道的一部分,该文件包含来自多个患者的基因组(这意味着即使压缩文件也很大,例如 3-5GB)。
我的问题是 运行ning 在 运行ning 这个脚本时内存不足。它正在 运行 GCP 高内存虚拟机中。
我希望有一种方法可以优化内存使用,这样就不会失败。我调查了一下,但什么也没发现。
#!/bin/bash
for filename in ./*.vcf.gz; do
[ -e "$filename" ] || continue
name=${filename##*/}
base=${name%.vcf.gz}
bcftools query -l "$filename" >> ${base}_list.txt
for line in `cat ${base}_list.txt`; do
bcftools view -s "$line" "$filename" -o ${line}.vcf.gz
gzip ${line}.vcf
done
done
如果您在使用 bcftools query
/view
或 gzip
时 运行 内存不足,请在手册中查找可能减少内存占用的选项。如果是 gzip,您也可以切换到替代实现。您甚至可以考虑完全切换压缩算法(zstd 非常好)。
不过,我感觉问题可能出在 for line in `cat ${base}_list.txt`;
。整个文件 ..._list.txt
在循环甚至开始之前就被加载到内存中。此外,以这种方式读取行有各种各样的问题,比如在空白处拆分行,扩展像 *
这样的 glob 等等。改用这个:
while read -r line; do
bcftools view -s "$line" "$filename" -o "$line.vcf.gz"
gzip "$line.vcf"
done < "${base}_list.txt"
顺便说一句:您确定要 bcftools query -l "$filename" >> ${base}_list.txt
到 追加 。每次执行脚本时,文件 ${base}_list.txt
都会不断增长。考虑使用 >
而不是 >>
.
覆盖文件
但是,在那种情况下,您可能根本不需要该文件,因为您可以使用它来代替:
bcftools query -l "$filename" |
while read -r line; do
bcftools view -s "$line" "$filename" -o "$line.vcf.gz"
gzip "$line.vcf"
done
您可以尝试在每个文件上使用 split
(变为恒定大小),然后 gzip 文件拆分。
此 bash 脚本旨在成为处理压缩 .vcf 文件的管道的一部分,该文件包含来自多个患者的基因组(这意味着即使压缩文件也很大,例如 3-5GB)。
我的问题是 运行ning 在 运行ning 这个脚本时内存不足。它正在 运行 GCP 高内存虚拟机中。
我希望有一种方法可以优化内存使用,这样就不会失败。我调查了一下,但什么也没发现。
#!/bin/bash
for filename in ./*.vcf.gz; do
[ -e "$filename" ] || continue
name=${filename##*/}
base=${name%.vcf.gz}
bcftools query -l "$filename" >> ${base}_list.txt
for line in `cat ${base}_list.txt`; do
bcftools view -s "$line" "$filename" -o ${line}.vcf.gz
gzip ${line}.vcf
done
done
如果您在使用 bcftools query
/view
或 gzip
时 运行 内存不足,请在手册中查找可能减少内存占用的选项。如果是 gzip,您也可以切换到替代实现。您甚至可以考虑完全切换压缩算法(zstd 非常好)。
不过,我感觉问题可能出在 for line in `cat ${base}_list.txt`;
。整个文件 ..._list.txt
在循环甚至开始之前就被加载到内存中。此外,以这种方式读取行有各种各样的问题,比如在空白处拆分行,扩展像 *
这样的 glob 等等。改用这个:
while read -r line; do
bcftools view -s "$line" "$filename" -o "$line.vcf.gz"
gzip "$line.vcf"
done < "${base}_list.txt"
顺便说一句:您确定要 bcftools query -l "$filename" >> ${base}_list.txt
到 追加 。每次执行脚本时,文件 ${base}_list.txt
都会不断增长。考虑使用 >
而不是 >>
.
覆盖文件
但是,在那种情况下,您可能根本不需要该文件,因为您可以使用它来代替:
bcftools query -l "$filename" |
while read -r line; do
bcftools view -s "$line" "$filename" -o "$line.vcf.gz"
gzip "$line.vcf"
done
您可以尝试在每个文件上使用 split
(变为恒定大小),然后 gzip 文件拆分。