wget을 사용하여 압축(bgz) 파일의 특정 열만 다운로드하는 방법은 무엇입니까?

wget을 사용하여 압축(bgz) 파일의 특정 열만 다운로드하는 방법은 무엇입니까?

182GB 압축 파일(압축되지 않은 파일)을 다운로드해야 합니다.실리콘을 통해). 그러나 파일의 처음 5개 열(약 1GB)만 필요합니다.

파일의 하위 집합을 다운로드하는 데 사용할 수 있는 멋진 쉘 마법이 있습니까?

콘텐츠의 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

전체 파일을 다운로드해야 하지만 필터링된 파일만 디스크에 기록됩니다.

데비안에서는 이 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

전혀 존재하지 않습니다.

자료를 봤는데 말씀하신대로 파일이 커서 다운은 안됐네요.

두 번째로 말씀하신 것은 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).
  • 행 계산을 구현하고 마지막으로 처리된 행을 센티넬 파일에 저장하더라도 처리 중에 스크립트가 충돌하면 처음부터 다시 다운로드하고 저장된 행에 도달할 때까지 기다리거나 이 경우에는 재부팅 시 모든 것을 다시 처리하기가 더 쉬워졌습니다.
  • 추출된 "처음 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 파일이 내부적으로 데이터를 저장하는 방식이라는 것은 예상치 못한 것 같습니다.

  • 데이터를 코드로 가져오는 대신 코드를 데이터로 가져올 수 있습니다. 분명히 데이터는 여러 클라우드에 저장됩니다. 이들 중 하나에 테넌트가 있는 경우 데이터에 더 빠르게 액세스하고 로컬 시스템에 다운로드하기 전에 저장할 수 있을 만큼 작게 필터링할 수 있습니다.

관련 정보