包含 sort 和 awk 的管道将太多文件写入磁盘,同时从文件中随机获取行,最终由于存储不可用而失败

包含 sort 和 awk 的管道将太多文件写入磁盘,同时从文件中随机获取行,最终由于存储不可用而失败

我的 SSD 上有大约 500 GB 的可用磁盘空间。我正在尝试对 10 个 gzip 压缩文件(每个文件大小约为 25GB)运行操作。但是,当我在 for 循环中执行此操作时,我一直会耗尽存储空间,parallel因为在同一目录中sort写入了很多内容temporary files,并且显然不会自行清理。

我试图从这些文件中随机获取一定数量的行。

bcftools view "${FILES[i]}".vcf.gz | awk '{printf("%f\t%s\n",rand(),$0);}' | sort -t $'\t' -T . -k1,1g | head -n "${SUBSET_COUNT[i]}" | cut -f 2- >> "${FILES[i]}"_"${SUBSET_COUNT[i]}"_subset.vcf &

此操作对每个文件大约需要 1 小时(当我一个接一个地执行时),但我想并行执行此操作,因为我需要对更多批次的此类文件重复此操作。

答案1

我真的不明白为什么你要采取这种方法,我怀疑它无论如何都不会起作用,因为rand()它没有被重新初始化并且可能总是给出完全相同的输出。尝试一下:

 $ for i in {1..10}; do awk -v i=$i 'BEGIN{print "Try "i",rand="rand()}'; done
Try 1,rand=0.924046
Try 2,rand=0.924046
Try 3,rand=0.924046
Try 4,rand=0.924046
Try 5,rand=0.924046
Try 6,rand=0.924046
Try 7,rand=0.924046
Try 8,rand=0.924046
Try 9,rand=0.924046
Try 10,rand=0.924046

无论如何,整个事情看起来太复杂了,你可以使用shuf

bcftools view file.vcf.gz | shuf -n 100 > newfile.vcf

这将从输入中随机选取 100 行。当然,这不是一个有效的 VCF 文件,它需要标头。因此,如果您想生成有效的 VCF,请将标头添加到每个文件,然后随机选择 N 个非标头行:

zgrep '^#' file.vcf.gz > newfile.vcf &&
zgrep -v '^#' file.vcf.gz | shuf -n 100 >> newfile.vcf

或者,更好的是,避免编写未压缩的文本:

zgrep '^#' file.vcf.gz | bgzip > newfile.vcf.gz &&
zgrep -v '^#' file.vcf.gz | shuf -n 100 | bgzip >> newfile.vcf.gz

相关内容