Список полных строк на основе одного поля намного быстрее, чем grep - PullRequest
1 голос
/ 29 февраля 2020

Мне нужно что-то {bash?} Для выполнения sh следующего, но гораздо более быстрого

grep -w -f position.txt build37.txt > genetic.map  

- только с целыми словами - иначе 55550 будет включать 17555508, 26155550 и c из заказать или не хотел; файл position.txt содержит 34 034 строки {числа} в 1 столбце; build37.txt содержит 3 303 900 строк в 4 столбцах; вся строка требуется в порядке их появления. geneti c .map после завершения будет иметь 34 034 строки в 4 столбцах

ПРИМЕРЫ:

position.txt
{Line#1:} 14228077

build37.txt
{Line#12,644:} chr1 14228077    6.339762    29.633830

genetic.map
{Line#1:} chr1  14228077    6.339762    29.633830

Спасибо!

-Более-

build37.txt: {Первые несколько строк}

Chromosome  Position(bp)    Rate(cM/Mb) Map(cM)
chr1    55550   2.981822    0.000000
chr1    82571   2.082414    0.080572
chr1    88169   2.081358    0.092229
chr1    254996  3.354927    0.439456
chr1    564598  2.887498    1.478148
chr1    564621  2.885864    1.478214
chr1    565433  2.883892    1.480558
chr1    568322  2.887570    1.488889
chr1    568527  2.895420    1.489481
chr1    721290  2.655176    1.931794
chr1    723819  2.669992    1.938509
chr1    728242  2.671779    1.950319
chr1    729948  2.675202    1.954877

позиции.txt: {придумано как пример}

82571
564621
565433
721290

geneti c .map {требуемый}

chr1    82571   2.082414    0.080572
chr1    564621  2.885864    1.478214
chr1    565433  2.883892    1.480558
chr1    721290  2.655176    1.931794

Мои извинения! В столбце позиции {номер два} файла build37.txt имеется 569 дубликатов. Мне понадобятся два идентификатора: чтобы получить правильные строки.

chr1  123456
chr6  123456

Я перепробовал все предложенные решения ... Возможно, потому что я ошибался в своих справочных данных, которые лучше запрашивать с использованием ДВУХ полей вместо ОДНОГО, результаты были на 357-569 строк длиннее, чем требовалось и ожидалось

Я переместил свой проект на windows {XP} и получил лучшие результаты с:

findstr /g:chr.pos.txt build37.txt > genetic.map

Результаты оказались на 44 строки длиннее, чем требовалось, и ожидаемые {лучше в любом случае}
FINDSTR: / C игнорируются / L не имеет значения / R может быть более точным, но обрабатывается медленно, со скоростью 71 строки в минуту в> geneti c .map

Обсуждение плохо документированных возможностей findstr по адресу: Каковы недокументированные возможности и ограничения команды Windows FINDSTR?

chr.pos .txt:

chr1    14228077
chr1    14228490  
...
chr22   49783510
chr22   49784152

Ответы [ 3 ]

3 голосов
/ 29 февраля 2020

Решение, которое я предложил выше с fgrep , не будет иметь большого значения. Лучше использовать инструмент join , если все в порядке для сортировки файлов position.txt и build37.txt.

join -1 1 -2 2 <(sort -k 1 position.txt) <(sort -k 2 build37.txt) | awk '{print $2, $1, $3, $4}'

Можно протестировать это решение, если вы может предоставить небольшое подмножество файлов position.txt и build37.txt.

1 голос
/ 29 февраля 2020

Вы должны гораздо больше беспокоиться о точности, чем об эффективности, когда пытаетесь использовать grep для сопоставления по одному полю, поскольку у grep нет понятия «поля». Просто используйте awk:

$ awk 'NR==FNR{pos[$1]; next} $2 in pos' position.txt build37.txt
chr1    82571   2.082414    0.080572
chr1    564621  2.885864    1.478214
chr1    565433  2.883892    1.480558
chr1    721290  2.655176    1.931794

Это будет быстро и надежно, так как он выполняет поиск ha sh, используя точно / только строки, которые появляются в столбце положений в build37.txt, точно / только против содержимое файла position.txt.

1 голос
/ 29 февраля 2020

Попробуйте:

fgrep -w -f position.txt build37.txt > genetic.map  

fgrep быстрее, чем grep , когда сопоставляемый шаблон является не регулярным выражением, а фиксированной строкой, как в пример, который вы указали при поиске строки 14228077.

...