Читать файл построчно с GNU параллельно - PullRequest
1 голос
/ 07 апреля 2020

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

chr1  1  5  ID1 HK1
chr2  2  8  ID2 HK3
...

Я хочу извлечь все строки для каждого идентификатора и записать их в соответствующий файл для этого идентификатора. Следующий код работает просто отлично, но я хотел бы распараллелить его с GNU parallel, так как это слишком медленно только с одним ядром (а у меня 72):

while IFS= read -r line
    do  
        a=$(echo "$line" | cut -f 4- | cut -f -1)
        b=$(echo "$line" | cut -f -3)
        echo $b >> "$a.bed"
    done < "file"

Я делал это раньше с grep, но так как некоторые файлы имеют> 800M строк, это тоже было слишком медленно. Как бы я передал это на GNU parallel правильный путь? Спасибо!

Ответы [ 3 ]

1 голос
/ 10 апреля 2020

Если у вас 800M строк, я думаю, вам нужно что-то быстрее, чем выполнение задания для каждой строки.

Так как насчет:

sort --parallel=100 -k4 input.tsv |
  parallel --pipe --group-by 4 --colsep '\s+' -kN1 'cat > num{#}.bed'

newname() {
    head -n1 "$1" | parallel --colsep '\s+' mv "$1" {4}.bed
}
export -f newname
ls num*bed | parallel newname 

В моей системе это делает 100M строк в 15 минут.

1 голос
/ 07 апреля 2020

Оказывается, GNU parallel имеет возможность читать файл построчно и передавать строку в качестве аргумента: parallel -a. Я изменил свой код на:

parallel -j 60 -a temp ./make_file.sh {}
0 голосов
/ 08 апреля 2020

Вам не нужны parallel или xargs -p, когда вы улучшаете свой процесс.
Ваш текущий l oop делает 3 разных cut процесса для каждой строки в файле. Подумайте о том, чтобы отрезать надрез над головой чем-то вроде

while IFS= read -r f1 f2 f3 f4 f5
    do  
        echo "${f3}" >> "${f4}.bed"
    done < "file"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...