wgetを使用して圧縮(bgz)ファイルの特定の列のみをダウンロードする方法は?

wgetを使用して圧縮(bgz)ファイルの特定の列のみをダウンロードする方法は?

182 GBの圧縮ファイル(圧縮されていないファイル)をダウンロードする必要があります。シリコンを通して)。ただし、ファイルの最初の5列(約1 GB)のみが必要です。

ファイルのサブセットをダウンロードするために使用できる素晴らしいシェル魔法はありますか?

コンテンツの99%を削除するためにファイル全体をダウンロードすると、サーバーのストレージ容量が実際に消費されます。

ダウンロード中のアイテム: gnomad.genomes.v3.1.2.sites.chr1.vcf.bgz~からgnomad.broadinstitute.org

代替ソリューションを歓迎します。圧縮されていないファイルにも機能するソリューションに興味があります。

要点は、ファイルのサブセットのみが必要なときに大容量ファイルをダウンロードしたくない場合はどうすればよいですか?

答え1

ファイルをダウンロードし、フィルタリングし、結果をローカルディスクに書き込むことができます。

curl https://storage.googleapis.com/gcp-public-data--gnomad/release/3.1.2/vcf/genomes/gnomad.genomes.v3.1.2.sites.chr1.vcf.bgz |
    bgzip -d |
    cut -f1-5

ファイル全体をダウンロードする必要がありますが、フィルタ処理されたファイルのみがディスクに書き込まれます。

Debian では、このbgzipコマンドはパッケージによって提供されますtabix。ただし、インストールされていない場合は(gzip)を使用して圧縮ファイルをzcat読み取ることもできます。bgzipcurl … | zcat | cut -f1-5


このパイプラインに必要なデータ記憶容量についていくつかの質問があります。これは実際の実行です。このシステムでは、圧縮しても、利用可能な合計ストレージ容量はわずか2GBで、ファイルをダウンロードして保存するのに必要な182GBとは離れています。

# How much disk space available in my current directory?
df -h .
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       7.9G  5.6G  2.0G  75% /

# Download and filter the file, saving only the result
curl https://storage.googleapis.com/gcp-public-data--gnomad/release/3.1.2/vcf/genomes/gnomad.genomes.v3.1.2.sites.chr1.vcf.bgz |
bgzip -d |
cut -f1-5 > bigfile

# What did we get, and how much disk space remains?
ls -lh bigfile
-rw-r--r-- 1 roaima roaima 1.7G Feb  7 05:09 bigfile

df -h .
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       7.9G  7.2G  347M  96% /

興味深いことに、ファイルは次のように見えました。厳しくないTSV(タブ区切り値)形式。 59,160,934行のうち942行にはタブ区切りデータは含まれていません。

file bigfile
bigfile: Variant Call Format (VCF) version 4.2, ASCII text, with very long lines

答え2

まったく存在しません。

資料を見ましたが、おっしゃった通りファイルが大きくてダウンはできませんね。

2番目に言ったのはTSVファイルです。

...バイナリTSV形式ファイルの最初の5列のみが必要です...

あなたの略語を正しく解釈すると、ファイルTSVと同じ意味ですTab Separated Value。この場合、バイナリファイルではなく平文ファイルです。もちろん、ある観点ではテキストファイルもバイナリファイルですが、この場合はテキストファイルについて話しています。

しかし、ファイルは実際に圧縮されました。

: curl -s -L https://storage.googleapis.com/gcp-public-data--gnomad/release/3.1.2/vcf/genomes/gnomad.genomes.v3.1.2.sites.chr1.vcf.bgz | file -
/dev/stdin: Blocked GNU Zip Format (BGZF; gzip compatible), block length 4462

誰かがすでに答えたように、これが意味するのは、ストリーミング技術を使用してファイルの圧縮を動的に解き、パイプを介して圧縮解除器に送信できることです。bgzcat私のディストリビューションにはないようですが、zcat非常に一般的で、私のディストリビューションにあり、この圧縮ストリームを読む方法を知っています。

: curl -s -L https://storage.googleapis.com/gcp-public-data--gnomad/release/3.1.2/vcf/genomes/gnomad.genomes.v3.1.2.sites.chr1.vcf.bgz | zcat | head -n 1              
##fileformat=VCFv4.2

詳しく調べると、ファイルの先頭に次のコメントがあります。

curl -L https://storage.googleapis.com/gcp-public-data--gnomad/release/3.1.2/vcf/genomes/gnomad.genomes.v3.1.2.sites.chr1.vcf.bgz | zcat | head -n 80
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0##fileformat=VCFv4.2
##hailversion=0.2.77-684f32d73643
##FILTER=<ID=AC0,Description="Allele count is zero after filtering out low-confidence genotypes (GQ < 20; DP < 10; and AB < 0.2 for het calls)">
##FILTER=<ID=AS_VQSR,Description="Failed VQSR filtering thresholds of -2.7739 for SNPs and -1.0606 for indels">
##FILTER=<ID=InbreedingCoeff,Description="InbreedingCoeff < -0.3">
##FILTER=<ID=PASS,Description="Passed all variant filters">
##INFO=<ID=AC,Number=A,Type=Integer,Description="Alternate allele count">
##INFO=<ID=AN,Number=1,Type=Integer,Description="Total number of alleles">
##INFO=<ID=AF,Number=A,Type=Float,Description="Alternate allele frequency">
##INFO=<ID=popmax,Number=A,Type=String,Description="Population with maximum allele frequency">
##INFO=<ID=faf95_popmax,Number=A,Type=Float,Description="Filtering allele frequency (using Poisson 95% CI) for the population with the maximum allele frequency">
##INFO=<ID=AC_non_v2_XX,Number=A,Type=Integer,Description="Alternate allele count for XX samples in non_v2 subset">
##INFO=<ID=AN_non_v2_XX,Number=1,Type=Integer,Description="Total number of alleles in XX samples in non_v2 subset">
##INFO=<ID=AF_non_v2_XX,Number=A,Type=Float,Description="Alternate allele frequency in XX samples in non_v2 subset">
##INFO=<ID=nhomalt_non_v2_XX,Number=A,Type=Integer,Description="Count of homozygous individuals in XX samples in non_v2 subset">
##INFO=<ID=AC_non_cancer_fin_XX,Number=A,Type=Integer,Description="Alternate allele count for XX samples of Finnish ancestry in non_cancer subset">
##INFO=<ID=AN_non_cancer_fin_XX,Number=1,Type=Integer,Description="Total number of alleles in XX samples of Finnish ancestry in non_cancer subset">
##INFO=<ID=AF_non_cancer_fin_XX,Number=A,Type=Float,Description="Alternate allele frequency in XX samples of Finnish ancestry in non_cancer subset">

最後の@943行はヘッダーで始めることができます。

: curl -s -L https://storage.googleapis.com/gcp-public-data--gnomad/release/3.1.2/vcf/genomes/gnomad.genomes.v3.1.2.sites.chr1.vcf.bgz | zcat | tail -n+943 | head -n 1 
#CHROM  POS ID  REF ALT QUAL    FILTER  INFO

データの最初の行のどれが実際に列区切り文字であるかを判断するのはあまりにも怠惰ですが、「\ t」が実際に列区切り文字であるようです。

: curl -s -L https://storage.googleapis.com/gcp-public-data--gnomad/release/3.1.2/vcf/genomes/gnomad.genomes.v3.1.2.sites.chr1.vcf.bgz | zcat | tail -n+944 | head -n 1 
chr1    10031   .   T   C   .   AC0;AS_VQSR AC=0;AN=56642;AF=0.00000;AC_non_v2_XX=0;AN_non_v2_XX=23674;AF_non_v2_XX=0.00000;nhomalt_non_v2_XX=0;AC_non_cancer_fin_XX=0;AN_non_cancer_fin_XX=1060;AF_non_cancer_fin_XX=0.00000;nhomalt_non_cancer_fin_XX=0;AC_non_neuro_nfe=0;AN_non_neuro_nfe=24462;AF_non_neuro_nfe=0.00000;nhomalt_non_neuro_nfe=0;AC_non_neuro_afr_XY=0;AN_non_neuro_afr_XY=5226;AF_non_neuro_afr_XY=0.00000;nhomalt_non_neuro_afr_XY=0;AC_non_neuro_nfe_XY=0;AN_non_neuro_nfe_XY=9974;AF_non_neuro_nfe_XY=0.00000;nhomalt_non_neuro_nfe_XY=0;AC_controls_and_biobanks_eas_XY=0;AN_controls_and_biobanks_eas_XY=392;AF_controls_and_biobanks_eas_XY=0.00000;nhomalt_controls_and_biobanks_eas_XY=0;AC_non_neuro_sas_XX=0;AN_non_neuro_sas_XX=260;AF_non_neuro_sas_XX=0.00000;nhomalt_non_neuro_sas_XX=0;AC_non_v2=0;AN_non_v2=44696;AF_non_v2=0.00000;nhomalt_non_v2=0;AC_non_topmed_nfe_XX=0;AN_non_topmed_nfe_XX=2800;AF_non_topmed_nfe_XX=0.00000;nhomalt_non_topmed_nfe_XX=0;AC_non_v2_mid=0;AN_non_v2_mid=192;AF_non_v2_mid=0.00000;nhomalt_non_v2_mid=0;AC_non_topmed_sas=0;AN_non_topmed_sas=1114;AF_non_topmed_sas=0.00000;nhomalt_non_topmed_sas=0;AC_non_cancer_eas_XX=0;AN_non_cancer_eas_XX=746;AF_non_cancer_eas_XX=0.00000;nhomalt_non_cancer_eas_XX=0;AC_amr_XY=0;AN_amr_XY=3650;AF_amr_XY=0.00000;nhomalt_amr_XY=0;AC_non_v2_nfe_XX=0;AN_non_v2_nfe_XX=12970;AF_non_v2_nfe_XX=0.00000;nhomalt_non_v2_nfe_XX=0;AC_controls_and_biobanks_XY=0;AN_controls_and_biobanks_XY=6960;AF_controls_and_biobanks_XY=0.00000;nhomalt_controls_and_biobanks_XY=0;AC_non_neuro_asj_XY=0;AN_non_neuro_asj_XY=722;AF_non_neuro_asj_XY=0.00000;nhomalt_non_neuro_asj_XY=0;AC_oth=0;AN_oth=782;AF_oth=0.00000;nhomalt_oth=0;AC_non_topmed_mid_XY=0;AN_non_topmed_mid_XY=82;AF_non_topmed_mid_XY=0.00000;nhomalt_non_topmed_mid_XY=0;AC_non_cancer_asj_XX=0;AN_non_cancer_asj_XX=770;AF_non_cancer_asj_XX=0.00000;nhomalt_non_cancer_asj_XX=0;AC_sas_XY=0;AN_sas_XY=860;AF_sas_XY=0.00000;nhomalt_sas_XY=0;AC_non_neuro_fin=0...

これはあなたのデータです。

今質問は次のとおりです。

  • ファイルだからシリコンを通して、これは基本的にもう少し一般的です。CSV形式は残念ながら、行中心形式であることを意味します。いいえ熱指向とは、次のことを意味します。
    • 渡されるデータ単位は行です。
    • 入ってくる行は列に分かれ、その逆も同様です。
    • つまり、最初の5つの列のみを「のみ」取得するには、ファイル内のすべての行にアクセスする必要があります。
    • 行の長さが予期しない/予測できないため、データ構造が不規則であるため、意味のある方法で必要なバイト範囲を計算できません。
  • ファイルがbgzip圧縮されているため、とにかくバイト範囲は使用できません。
    • HTTPサーバーですぐにgzip圧縮を使用すると、サイズ計算エラーが原因でこれらのファイルのバイト範囲が破損することがよくあります。
    • ファイルがあらかじめ圧縮されているか(ダウンロードディレクトリに保存されているか)(そしてhttpd / nginxによって動的に圧縮されているかどうか)はわかりません。
    • ファイルサイズを考慮すると事前に圧縮されている可能性があるため、理論的にはバイト範囲が機能する可能性がありますが、圧縮されていない個々の行を対応するBGZIPチャンクにマップするにはまだインデックスが必要です。これはレベルの上の作業かもしれません(家庭でこのような質問をします。時間投資率を考慮すると、私のレベルでも収益が出ないようです。(週/月が必要)
    • 索引付けが正常に機能していても、ファイル全体をダウンロード/解析する必要があり、ファイルがアップストリームに変更されても索引付けは中断されます。
  • 最も簡単な方法は、接続が数時間/日間続く場合でも接続が失われないようにGoogleダウンロードサーバーを設定することです。

最後のポイントを考慮すると、@ user10489が言ったことを行うことができます。

  1. Googleサーバーでファイルストリーミングを開始し、curl次にパイプします。zcat
  2. 出力の終わりをzcatすばやく整理されたいくつかのスクリプト(perl、python、php、lua)の入力にパイプします。
  3. タブで区切られた最初の5つの列を使用して、スクリプトから入ってくる各行を解析し、その列を別々のローカルデータファイル(TSVまたは推奨sqlite3)に保存します。また、上記のデータセットの先頭にあるコメントを無視する必要があります。

最終的な使用法は次のとおりです。

: curl -s -L https://storage.googleapis.com/gcp-public-data--gnomad/release/3.1.2/vcf/genomes/gnomad.genomes.v3.1.2.sites.chr1.vcf.bgz | zcat | myscript my-outfile.tsv

あなたは理解しました。

これはあなたの能力に応じて数分/時間以内に完了することができますが、今では次の問題に直面します。

  • 数時間無人で実行できるようにパイプラインを設定する必要があります(tmux、screen)。
  • 行計算を実装して最後に処理された行をCentinelファイルに保存しても、処理中にスクリプトがクラッシュした場合は、最初から再度ダウンロードして保存された行に到達するのを待つか、この場合は再起動時にすべてを再処理するのが簡単になりました。 。
  • 抽出された「最初の5列のみ」が圧縮された128GBよりはるかに小さいという事実がわかりません。とにかくプロセスのスペースが足りなくなります。
  • 最後に、Googleサーバーに「ダウンロード接続が長すぎる」保護がないため、curlパイプヘッダへのリンクを早期にブロックできるかどうかはわかりません。つまり、まだ動作します。不可能ファイル全体を下に転送します。

したがって、あなたの場合は、プロジェクト/研究責任者または管理者に行き、リソース(ドライブ、おそらくVM /ノード)を要求し、期待どおりにファイル全体をダウンロードしてローカルで前処理します。前処理された5列ファイルの長さ/サイズを分析してサーバーにアップロードするだけです。

パイプラインをブロックしないGoogleサーバーに依存せずに、必要に応じてパイプラインを再実行して調整できます。 「ストレージに5列しか保管できませんか?」について心配する必要はありません。

お役に立てば幸いです。

答え3

  • ファイルが解凍された場合は、httpプロトコルからバイト範囲をダウンロードできます。しかし、インデックスがなければまったく役に立たないかもしれません。
  • ファイルがストリーミング圧縮で圧縮されている場合は、そのコンテンツを解凍する前にファイル全体をダウンロードする必要があります。多くのストリーミングコンプレッサーはチャンクのシーケンシャル圧縮を実際に実行しますが、基本的にはそのチャンクのインデックスがなければ実行可能ではなく、一連のチャンクではなく単一の列を取得したい場合は不可能です。
  • 問題がネットワーク帯域幅ではなくディスク容量の場合は、さまざまなオプションがあります。コンテンツをメモリにダウンロードし、メモリからストリーミングして解凍し、圧縮されていないデータを必要な列を抽出して記録するプロセスに送信します。これはすべて、単一のパイプラインからwget -O - | bgzcat |標準入力への入力を受け取り、標準出力またはファイルに必要な内容を書き込むストリームベースのツールを使用して実行できます。

答え4

他の人が指摘したように、wgetを使用してファイルの特定の列のみをダウンロードすることは技術的に不可能です。

データをダウンロードする前にフィルタリングする必要があります。つまり、データはサーバー側でフィルタリングする必要があります。 HTTPSサーバーの単純なzipファイルはこの機能を提供しません。

他の選択肢:

  • 他の方法でデータにアクセスできる場合は、見てみる価値があります。タブ区切り値(TSV)ファイルは実際にはデータベースダンプの出力であり、アプリケーションプログラミングインターフェース(API)を使用してデータベースを直接照会できます。おそらく、REST(Representational State Transfer)APIやその他の手段に基づいてデータをカスタマイズする方法があります。そのようなインターフェースが公に利用可能かどうかをデータプロバイダに確認することができます。このように巨大なTSVファイルが内部的にデータを保存する方法であることは予期しないようです。

  • データをコードにインポートするのではなく、コードをデータにインポートできます。明らかに、データは複数のクラウドに保存されます。これらのいずれかにテナントがある場合は、データにすばやくアクセスし、ローカルシステムにダウンロードする前に保存できるほど小さくフィルタリングできます。

関連情報