разбор огромного файла с awk и извлечение подмножества

У меня огромный файл, который выглядит так

chr10 98072 1 chr10 98073 1 chr10 98074 1 chr10 98075 2 chr10 98076 2 chr10 98077 3 chr10 98078 5 chr10 98079 5 chr11 98080 5 chr12 98081 5 

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

 awk '$1 ~ /^chr10$/{print}; $1 !~ /^chr10$/{exit}' cov.txt > subset.txt 

Это хороший способ заставить awk не просматривать весь файл. Мой файл уже отсортирован по хромосоме

благодаря

  • Получить логическое имя беспроводной сети
  • Исключить строки, которые имеют менее 23 столбцов
  • Как применить команду awk для всех полей, за исключением нескольких определенных строк
  • awk: удалить строки, где поля 1 и 2 дублируют
  • как выбрать часть строки и вставить ее в другой файл?
  • Значения uniq первого столбца grep
  • Извлечение многострочного регулярного выражения без вкладок
  • Переупорядочить несколько линейных блоков с помощью Sed
  • 5 Solutions collect form web for “разбор огромного файла с awk и извлечение подмножества”

    Использование sed :

     sed -n '/^chr10[^0-9]/ { p; b; }; q' cov.txt > subset.txt 

    Это все еще предполагает, что группа chr10 находится в самом начале файла.

     awk '$1=="chr10"{print; next}{exit}' cov.txt > subset.txt 

    Тесты: перенаправлено на /dev/null для 12,947,909 chr10 записей плюс еще несколько chr11 , chr12 и более на общую сумму 99 063 774 строки – выходы идентичны (то же md5sum). Число выходных линий = 12 947 909 – заказывается быстрее всего медленнее :

    steve: awk '{ if($1 == "chr10") { print } else { exit } }' cov.txt >/dev/null

     real 0m5.963s user 0m5.896s sys 0m0.064s 

    Peter.O: awk '$1=="chr10"{print; next}{exit}' cov.txt >/dev/null awk '$1=="chr10"{print; next}{exit}' cov.txt >/dev/null

     real 0m6.553s user 0m6.484s sys 0m0.068s 

    kos: perl -pe '!/chr10/&&exit' cov.txt >/dev/null

     real 0m8.658s user 0m8.545s sys 0m0.112s 

    steve: sed -n '/^chr10[^0-9]/ { p; b; }; q' cov.txt >/dev/null sed -n '/^chr10[^0-9]/ { p; b; }; q' cov.txt >/dev/null

     real 0m17.130s user 0m17.077s sys 0m0.052s 

    user3138373: awk '$1 ~ /^chr10$/{print}; $1 !~ /^chr10$/{exit}' cov.txt >/dev/null awk '$1 ~ /^chr10$/{print}; $1 !~ /^chr10$/{exit}' cov.txt >/dev/null

     real 0m18.621s user 0m18.541s sys 0m0.080s 

    Попытайтесь это, казалось, немного быстрее в моем рудиментарном испытании. Избегает выполнения обработки регулярных выражений.

     [root@localhost tmp]# wc -l cov.txt 34970568 cov.txt [root@localhost tmp]# time awk '$1 ~ /^chr10$/{print}; $1 !~ /^chr10$/{exit}' cov.txt > subset.txt real 0m23.897s user 0m22.031s sys 0m1.556s [root@localhost tmp]# time awk '{ if($1 == "chr10") { print } else { exit } }' cov.txt > subset.txt real 0m16.784s user 0m14.731s sys 0m1.661s [root@localhost tmp]# 

    Пробовал также подход sed lcd047

     [root@localhost tmp]# time sed -n '/^chr10[^0-9]/ { p; b; }; q' cov.txt > subset.txt real 0m38.343s user 0m36.609s sys 0m1.546s [root@localhost tmp]# 

    Использование простого старого grep было самым быстрым, хотя он читал весь файл

     [root@localhost tmp]# time grep "^chr10" cov.txt >subset.txt real 0m6.546s user 0m4.932s sys 0m1.577s [root@localhost tmp]# 

    Считалось бы, что grep -F будет быстрее, но, похоже, не было. Постоянно более 7 секунд.

     [root@localhost tmp]# time grep -F chr10 cov.txt >subset.txt real 0m7.317s user 0m6.109s sys 0m1.173s [root@localhost tmp]# 

    Более эффективно, сделайте это с помощью egrep :

     egrep '^chr10{space or tab}' cov.txt 

    Или, если содержимое похоже на то, что вы показали,

     grep -w chr10 cov.txt 

    Поскольку файл сортируется и в соответствии с вашими линиями комментариев, начинающимися с chr10 , всегда находятся в начале файла, используя Perl:

     < cov.txt perl -pe '!/chr10/&&exit' > subset.txt 

    Таким образом, сценарий будет выходить с первого появления несоответствия.

    Тестирование этого запуска в файле с 1000000 совпадающими строками, хранящемся в памяти (полученном путем добавления chr10 98072 1 1000000 раз в пустой файл) запускается в chr10 98072 1 сроки:

     ~/tmp$ < cov.txt wc -l 1000000 ~/tmp$ time < cov.txt perl -pe '!/chr10/&&exit' > subset.txt real 0m0.631s user 0m0.624s sys 0m0.004s ~/tmp$ < subset.txt wc -l 1000000 
    Linux и Unix - лучшая ОС в мире.