Вот несколько мыслей с примерами.Для целей тестирования я создал тестовый набор, поскольку мини-версия Yours example_mini.fastq имеет размер 145 МБ, а IDarray имеет 999 элементов (интересов).
Ваша версия имеет такую производительность (более 2 минут в пространстве пользователя):
$ time for i in "${arr[@]}"; do grep -A 3 "${i}" example_mini.fastq; done 1> out.txt
real 3m16.310s
user 2m9.645s
sys 0m53.092s
$ md5sum out.txt
8f199a78465f561fff3cbe98ab792262 out.txt
Первое обновление grep до конца grep после первого совпадения -m 1
. Я предполагаю, что идентификатор интереса уникален.Это сужает на 50% сложности и занимает около 1 минуты в пользовательском пространстве:
$ time for i in "${arr[@]}"; do grep -m 1 -A 3 "${i}" example_mini.fastq; done 1> out.txt
real 1m19.325s
user 0m55.844s
sys 0m21.260s
$ md5sum out.txt
8f199a78465f561fff3cbe98ab792262 out.txt
Эти решения линейно зависят от количества элементов.Вызвать n раз grep для огромного файла.
Теперь давайте внедрим в AWK только для одного запуска, я экспортирую IDarray во входной файл, чтобы я мог обработать за один запуск.Я загружаю большой файл в ассоциативный массив для каждого идентификатора, а затем зацикливаю 1x массив идентификаторов для поиска.Это общий сценарий, в котором Вы можете определить регулярное выражение и количество строк после печати.Это имеет сложность только с одним прогоном сравнения файлов + N.Это на 2000% больше ускорения:
$ for i in "${arr[@]}"; do echo $i; done > IDarray.txt
$ time awk '
(FNR==NR) && (linesafter-- > 0) { arr[interest]=arr[interest] RS $0; next; }
(FNR==NR) && /^@/ { interest=$1; arr[interest]=$0; linesafter=3; next; }
(FNR!=NR) && arr[$1] { print(arr[$1]); }
' example_mini.fastq IDarray.txt 1> out.txt
real 0m7.044s
user 0m6.628s
sys 0m0.307s
$ md5sum out.txt
8f199a78465f561fff3cbe98ab792262 out.txt
Как в заголовке, если вы действительно можете подтвердить, что каждая четвертая строка является идентификатором интереса, и три строки после нее будут напечатаны.Вы можете упростить это и ускорить еще на 20%:
$ for i in "${arr[@]}"; do echo $i; done > IDarray.txt
$ time awk '
(FNR==NR) && (FNR%4==1) { interest=$1; arr[interest]=$0; next; }
(FNR==NR) { arr[interest]=arr[interest] RS $0; next; }
(FNR!=NR) && arr[$1] { print(arr[$1]); }
' example_mini.fastq IDarray.txt 1> out.txt
real 0m5.944s
user 0m5.593s
sys 0m0.242s
$ md5sum out.txt
8f199a78465f561fff3cbe98ab792262 out.txt
Для файла объемом 1,5 ГБ с 999 элементами время поиска составляет:
real 1m4.333s
user 0m59.491s
sys 0m3.460s
Так, согласно моим прогнозам на моей машинеВаш 15-гигабайтный пример с 10-килобайтными элементами займет около 16 минут в пользовательском пространстве.