1

此 bash 脚本旨在成为处理压缩 .vcf 文件的管道的一部分,该文件包含来自多个患者的基因组(这意味着即使压缩文件也很大,例如 3-5GB)。

我的问题是我在运行这个脚本时总是内存不足。它在 GCP 高内存 VM 中运行。

我希望有一种方法可以优化内存使用,这样就不会失败。我调查了一下,但什么也没找到。

#!/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
4

2 回答 2

4

如果您在使用bcftools query/viewgzip手册中查找可能减少内存占用的选项时内存不足。在 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
于 2021-01-21T22:14:15.480 回答
0

您可以尝试split在每个文件上使用(变为恒定大​​小),然后 gzip 文件拆分。

https://man7.org/linux/man-pages/man1/split.1.html

于 2021-01-21T22:40:24.200 回答