簡體   English   中英

Linux合並巨大的gzip文件並保持只有交集

[英]Linux merge huge gzip files and keep only intersection

我有一個名為“main.txt”的制表符分隔文件,我試圖從許多名為“chr1.info.gz”,“chr2.info.gz”,“chr3.info”的多個gz文件中向此文件添加信息。 gz“等等,它包含比主文件多很多的行。 請注意這些文件是使用gzip壓縮的,我不能先解壓縮它們並保存它們,因為它們是巨大的文件(我沒有空間來執行此操作)。

我想在主文件中將名為“name_id”(第6個字段)的列與多個不同文件(第3個字段)中名為“rs_id”的匹配列進行匹配,並添加來自這些文件的附加信息,同時僅保留行在主文件中:

main.txt文件如下所示:

number maf effect se pval name_id
34 0.7844 0.2197 0.0848  0.009585 snp1
78 0.6655 -0.1577 0.0796  0.04772 snp2

像這樣的chr1.info.gz:

use pos rs_id a1 a2 a3 a4
f 10584 snp34 0 0 0 0
g 10687 snp35 0 0 0 0
t 13303 snp1 0 0 0 0

chr2.info.gz是這樣的:

use pos rs_id a1 a2 a3 a4
s 13328 snp67 0 0 0 0    
g 10612 snp2 0 0 0 0
t 13303 snp10 0 0 0 0

…等等

我想從其他文件中獲取添加信息的文件main.all.gz:

number maf effect se pval name_id use pos rs_id a1 a2 a3 a4
34 0.7844 0.2197 0.0848  0.009585 snp1 t 13303 snp1 0 0 0 0
78 0.6655 -0.1577 0.0796  0.04772 snp2 g 10612 snp2 0 0 0 0

我嘗試過“加入”,但看起來它需要解壓縮文件,對它們進行排序並保存它們,並且我得到的消息是我在設備上沒有足夠的空間(我不認為我有無論如何正確的代碼):

join -1 6 -2 3 <(zcat main.txt | sort -k6,6) <(zcat chr1.info.gz | sort -k3,3 ) > try.txt

我嘗試過使用awk但是我肯定做了幾件事,因為它給了我一個空文件,而且在使用多個文件時我遇到了問題。

我已經花了一天時間在這上面找不到一個好的解決方案,你能幫我解決一下嗎?

非常感謝你! -F

我是用Python做的。

將主文件讀入內存並從中生成一個字典(使用name_id作為鍵)。 然后流式傳輸每個info.gzip文件,並根據您找到的內容擴展dict中的信息。 (如果您不止一次找到某條線的信息,請考慮該怎么辦。)

然后以您需要的格式寫出dict。

這種方法有幫助嗎?

#!/usr/bin/env python

import gzip
from collections import OrderedDict

mainData = OrderedDict()  # or just {} if order is not important
with open('main.txt') as mainFile:
  pos = None
  for line in mainFile:
    elements = line.split()
    if pos is None:
      pos = elements.index('name_id')
      mainHeaders = elements
    else:
      mainData[elements[pos]] = elements

infoHeaders = None
for infoFileName in [ 'chr1.info.gz', 'chr2.info.gz' ]:
  with gzip.open(infoFileName) as infoFile:
    pos = None
    for line in infoFile:
      elements = line.split()
      if pos is None:
        pos = elements.index('rs_id')
        if infoHeaders is None:
          infoHeaders = elements
        else:
          if infoHeaders != elements:
            print "headers in", infoFileName, "mismatch"  # maybe abort?
      else:
        key = elements[pos]
        try:
          mainData[key] += elements
        except KeyError:
          pass  # this key does not exist in main

with gzip.open('main.all.gz', 'w') as outFile:
  outFile.write(' '.join(mainHeaders + infoHeaders) + '\n')
  for key, value in mainData.iteritems():
    outFile.write(' '.join(value) + '\n')

我的結果是這樣的:

number maf effect se pval name_id use pos rs_id a1 a2 a3 a4
34 0.7844 0.2197 0.0848 0.009585 snp1 t 13303 snp1 0 0 0 0
78 0.6655 -0.1577 0.0796 0.04772 snp2 g 10612 snp2 0 0 0 0

它不期望或生成制表符分隔文件(但為所有內容使用空格)。 您的示例數據看起來不像是分隔符;-)但是您可以將輸出代碼中的' ' ((空格)(最后一行)更改為'\\t'以使用制表符作為分隔符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM