Объедините 2 огромных файла, соответствующих нескольким столбцам, и сохраните порядок (соответствие печати и несоответствующие значения) – увеличьте масштаб с awk

У меня возникают проблемы с объединением данных из 2-х файлов. Это генетические данные с хромосомой, позицией, ссылкой и альтернативными аллелями, и мне нужно объединить файлы, сопоставляя все 4 из этих столбцов – с эталонным и альтернативным аллелями в любом направлении. Поэтому мне нужны столбцы $ 1, $ 2, $ 4 и $ 5 OR $ 1, $ 2, $ 5 и $ 4 в файле поиска, чтобы точно соответствовать столбцам $ 1, $ 5, $ 6 и $ 7 в файле данных. Очень важно, чтобы я сохранял точный порядок в файле данных – я не могу его сортировать (так грустно не могу использовать join – это предложенный ответ, который я нашел в других случаях такого рода вопросов).

Я использовал awk и получил код для файлов примеров с несколькими тысячами строк, но он не масштабируется для моего большого набора данных (файл поиска имеет> 300 миллионов строк, datafile – 30 миллионов) – предположительно, поскольку код требует сохранения в память 2 огромных массива для поиска. Любые предложения по масштабируемому коду («в perl? – у меня мало опыта») с благодарностью получены! Пожалуйста, будьте осторожны – я новичок-кодер, так извиняюсь за любые вопиющие недостатки в моем вопросе или коде!

  • Используйте sed для поиска и сохранения только строк с двумя альфа-символами в них
  • awk с утверждениями if
  • Как добавить слово для строки, в которой выполняется транспонирование
  • Множественное сопоставление столбцов и настройка с помощью awk
  • Найдите шаблон и вставьте # в начале 2 строки до этого и 1 строку после этого
  • Как удалить текст, сопоставляющий определенные шаблоны из файла
  • Формат файла поиска:

    1 10150 rs371194064 CT 1 10165 rs796884232 A AC 1 10177 rs367896724 A AC 1 10177 rs201752861 AC 1 10180 rs201694901 TC 1 10199 rs905327004 AT 1 10231 rs200279319 CA 1 10234 rs145599635 CT 1 10235 rs540431307 T TA 1 10235 rs1035249121 TA 1 10235 rs1035249121 TC 1 10241 rs960927773 TC 1 10247 rs796996180 TC 1 10248 rs148908337 AT 1 10249 rs774211241 AAC A 

    и формат моего файла данных

     1 chr1 chr1:10177 1:10177_A_AC 10177 A AC 1 chr1 chr1:10235 1:10235_T_TA 10235 T TA 1 chr1 chr1:10352 1:10352_T_TA 10352 T TA 1 chr1 chr1:10505 1:10505_A_T 10505 AT 1 chr1 chr1:10506 1:10506_C_G 10506 CG 1 chr1 chr1:10511 1:10511_G_A 10511 GA 1 chr1 chr1:10539 1:10539_C_A 10539 CA 1 chr1 chr1:10542 1:10542_C_T 10542 CT 1 chr1 chr1:10579 1:10579_C_A 10579 CA 

    Результат должен выглядеть так:

     1 rs367896724 1:10177_A_AC 10177 A AC A AC 1 rs540431307 1:10235_T_TA 10235 T TA T TA 1 chr1:10352 1:10352_T_TA 10352 T TA T TA 1 chr1:10505 1:10505_A_T 10505 ATAT 1 chr1:10506 1:10506_C_G 10506 CGCG 1 chr1:10511 1:10511_G_A 10511 GAGA 1 chr1:10539 1:10539_C_A 10539 CACA 1 chr1:10542 1:10542_C_T 10542 CTCT 1 chr1:10579 1:10579_C_A 10579 CACA 

    Код awk, который мне удалось получить для файла примера, выглядит следующим образом:

     awk 'BEGIN {OFS = "\t"} NR==FNR { #lookup file (323 million rows) key = $1 "," $2 "," $4 "," $5 present[key] = 1 ID[key] = $3 Ref[key] = $4 Alt[key] = $5 key1 = $1 "," $2 "," $4 "," $5 present1[key1] = 1 ID1[key1] = $3 Ref1[key1] = $4 Alt1[key1] = $5 next } { # my data file (3 million rows) key = $1 "," $5 "," $6 "," $7 key1 = $1 "," $5 "," $7 "," $6 if (present[key]) print $1, ID[key], $4, $5, $6, $7, Ref[key], Alt[key]; else if (present1[key1]) print $1, ID1[key1], $4, $5, $6, $7, Ref1[key1], Alt1[key1]; else print $1, $3, $4, $5, $6, $7, $6, $7 }' $lookupfile $mydatafile > $outputfile 

  • awk отдельные столбцы из 3
  • Могу ли я определить тип переменной awk?
  • Строки печати, если заданный столбец начинается с заглавной буквы
  • Использовать awk интерактивно через трубу
  • Простая переменная, установленная в Awk
  • Как обрабатывать ^ M в файлах csv с помощью sed & awk?
  • One Solution collect form web for “Объедините 2 огромных файла, соответствующих нескольким столбцам, и сохраните порядок (соответствие печати и несоответствующие значения) – увеличьте масштаб с awk”

    Проблема заключается не в хранении этого файла в памяти, а в сканировании таблицы поиска для каждой строки файла данных. Ваш код не показывает его, но за кулисами вы делаете 3'000'000 раз 323'000'000 / 2 = почти половину квадратичного сравнения строк, перемещая тысячи терабайт по вашей шине памяти. Даже для быстрой памяти с 200 Гбит / с это займет много часов.

    Таким образом, ключом к проблеме является сохранение таблицы поиска. Я предлагаю использовать двоичное дерево для экспоненциального сокращения времени выполнения. Вы можете сделать это на perl или C или на каком-либо другом языке, но в данный момент это станет не по теме.

    Набор инструментов unix не поможет вам с этой проблемой.

    Linux и Unix - лучшая ОС в мире.