Печать строк сжатого файла gz на основе другого индексного файла - PullRequest
0 голосов
/ 24 января 2019

Необходимо напечатать определенные строки большого файла txt.gz, используя индексный файл

Привет всем,

Я нашел несколько примеров для печати определенных строк несжатых файлов, ноне удалось найти решение для очень большого файла gz.

Мой индексный файл (idx.txt) выглядит следующим образом и содержит 700 000 индексов:

1745  
1746  
7379  
13920  
13921  
16681  
16682
...
...
...
54830241
54867703
54867710

Я хочу получить всеэти 700 000 строк в моем другом исходном файле, который представляет собой очень большой сжатый CSV-файл с 55 000 000 строк и выглядит следующим образом:

100035243,2,"Chronic obstructive pulmonary disease","SS","LETAIRIS","AMBRISENTAN","","Dyspnoea",NA,73,"F","","","CN"
100035672,1,"Myeloproliferative disorder","PS","JAKAFI","RUXOLITINIB","ORAL","Platelet count increased",20131206,48.501,"F","79.37","KG","OT"
100035914,1,"Multiple sclerosis","PS","GILENYA","FINGOLIMOD HYDROCHLORIDE","ORAL","Lymphocyte count decreased",20130718,47.154,"F","","","OT"
....

Что я пробовал до сих пор:

sed -nf idx.txt <(gzip -dc gzfile.gz) > output.txt  
awk 'NR==FNR{i[$0];next}i[FNR]' idx.txt <(gzip -dc gzfile.gz) > output.txt  

Обаочень медленные.
Есть мысли?

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Оба решения sed и awk выглядят хорошо.Вероятно, sed один быстрее, чем awk один.И, вероятно, они быстрее, чем вы можете получить.Чтобы сократить время ... уменьшите размер входного файла.

Еще одна вещь, которую вы можете сделать, - это остановить чтение после последней напечатанной строки, поэтому, если вы знаете, что последняя напечатанная строка будет находиться далеко от конца файлаВы можете избежать длительной декомпрессии:

sed -nf idx.txt <(gzip -dc gzfile.gz | head -n "$(sort -nr idx.txt | head -1)") > output.txt
0 голосов
/ 24 января 2019

ИМХО, ваш awk код выглядит нормально для меня, так что может быть 1 способ увеличить его скорость обработки. Хотя я не уверен (и поскольку ваши образцы не ясны, поэтому не проверяли также), если последняя запись в вашем файле id.txt намного меньше, чем общее количество строк в файле .gz, то вы можете выйти из awk Код и НЕ нужно читать Input_files, попробуйте один раз.

awk 'NR==FNR{i[$0]=$0;last=$0;next} i[FNR]{print} FNR!=NR && FNR>last{exit}' idx.txt <(gzip -dc gzfile.gz) > output.txt

Итак, я создаю переменную с именем last, значение которой должно быть значением последней строки ids.txt. Затем во втором условии я проверяю, больше ли номер строки, чем значение последней записи в ids.txt затем выйдите из кода.

РЕДАКТИРОВАТЬ: Изменен код OP с i[$0] на i[$0]=$0 в первом условии, так как условие i[FNR] будет работать только тогда, когда массив i имеет значения. Изменено после упоминания пользователя в комментариях.

PS: Это определенно сэкономит только время и только в том случае, если у вас есть огромная разница между значением последней строки в ids.txt и общим количеством строк, присутствующих в файле .gz. Так как я собираюсь с вашим утверждением, что у вас есть очень большие данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...