grep второй раз быстрее

Предположим, что я занимаюсь рекурсивным поиском grep . После просмотра результатов я хочу получить другой результат; например, я хочу добавить опцию -C 3 для 3 строк контекста. Я могу выполнить весь поиск снова с добавленной новой опцией, но я должен ждать то же время, что и раньше.

Есть ли какой-нибудь умный способ сделать grep быстрее выполнять второй поиск?

  • bash - извлекает имена файлов из html-файла, содержащего несколько ссылок
  • Найдите строки, начинающиеся с #define и заканчивающиеся на \
  • Как подсчитать количество строк для определенного типа файла в сжатом файле tgz?
  • Как подсчитать количество слов и напечатать строки, соответствующие точному шаблону?
  • Как я могу подсчитать количество строк в файле после соответствия grep?
  • ps aux | grep config vs ps aux | grep "confi "
  • Найти шаблон в XML с помощью команды unix
  • Как grep многострочный журнал postgresql?
  • 5 Solutions collect form web for “grep второй раз быстрее”

    Вы можете сохранить соответствующий список файлов и grep только в соответствующих файлах. Это будет намного быстрее. Например, вы можете использовать find + grep :

     find . -type f -exec grep -l 'PATTERN' {} \+ | xargs grep -H -C 3 'PATTERN' 

    Если вам нужно увидеть выход grep после первого запуска в find это немного сложнее, но все же довольно легко. Вам просто нужно использовать что-то подобное

     find -exec grep -H 'PATTERN' {} \+ | tee -a out.log |\ sed 's/^[^:]*://' | sort -u | xargs grep -C 3 'PATTERN' 

    И вывод будет сохранен в файле out.log.

    Второй раз должен быть быстрее (если grep связан с I / O), так как файл должен находиться в кеше операционной системы.

    Поскольку grep не сохраняет какое-либо состояние вообще и работает только с предоставленным входным параметром, нет возможности повторно использовать предыдущие результаты с помощью самой grep .

    Если вы регулярно сталкиваетесь с этой проблемой, вы можете захотеть просмотреть поисковые системы для настольных компьютеров или индексацию текста, чтобы улучшить время поиска, а также результаты.

    Если файлы все еще находятся в кеше диска, второй поиск будет быстрее.

    Если вы хотите ускорить поиск, вам нужно создать индекс. Это далеко за рамки работы grep: это инструмент поиска, а не инструмент индексирования. Полнотекстовая индексация командной строки? перечислены некоторые инструменты индексирования.

    Существуют способы, с помощью которых вы можете использовать grep для ускорения повторных поисков. Например, сначала получите список совпадающих файлов с grep -l . Если ваши имена файлов не содержат никаких пробелов или шаблонов оболочки *?\[ , Вы можете набивать имена файлов в переменной:

     f=$(grep -l -r foo .) grep foo $f grep -C3 foo $f grep foobar $f 

    Просто для чего-то другого …
    Следующий скрипт не использует grep во второй раз. Он полагается только на номера строк, собранные grep на первом шаге, и использует sed для распечатки.

    grep -HnZ используется на первом шаге: H для имени файла, n для номера строки и Z для нетекстового разделителя \x00 между именем файла и linenumber.

    Я не думаю, что это будет намного (если есть) быстрее, чем запуск grep над файлами, которые были идентифицированы в первом пути, потому что каждый из идентифицированных файлов должен быть отсканирован в любом случае. Кроме того, это неточно, если какие-либо соответствующие изменения в наборе данных вводятся на первом этапе. (Это только меня заинтересовало, так вот оно ..)

     # create 2 test files. printf '%s\n' {a..z} >junk1 printf '%s\n' {a..z} >junk2 # Make list of filenames and line numbers # then convert the list into a shell script # which uses 'sed' to list the lines grep -HnZ "[gms]" junk1 junk2 | # Make list of filenames and line numbers awk -v"C=2" 'BEGIN{ FS="[\x00:]" print "#!/bin/sh" } { negC=$2-C; if (negC<1){negC=1}; posC=$2+C } prev != $1 { if( prev ) print prev_grp "\"" prev = $1 prev_grp = "<\"" $1 "\" sed -nr \"" \ negC"i -- ("negC","$2","posC") "$1"\n\t"negC","posC"{p;b};" next } { prev_grp = prev_grp" " \ negC"i -- ("negC","$2","posC") "$1"\n\t"negC","posC"{p;b};" } END{ if( prev ) print prev_grp "\"" } '>junk.sh chmod +x junk.sh ./junk.sh 

    Это результат начальной команды grep , отображающей нуль как \x00

     junk1\x007:g junk1\x0013:m junk1\x0019:s junk2\x007:g junk2\x0013:m junk2\x0019:s 

    Вот сгенерированный скрипт

     #!/bin/sh <"junk1" sed -nr "5i -- (5,7,9) junk1 5,9{p;b}; 11i -- (11,13,15) junk1 11,15{p;b}; 17i -- (17,19,21) junk1 17,21{p;b};" <"junk2" sed -nr "5i -- (5,7,9) junk2 5,9{p;b}; 11i -- (11,13,15) junk2 11,15{p;b}; 17i -- (17,19,21) junk2 17,21{p;b};" 

    Вот результат grep-like (n, n, n) – это linenumbers (from, matching, to)

     -- (5,7,9) junk1 e f g h i -- (11,13,15) junk1 k l m n o -- (17,19,21) junk1 q r s t u -- (5,7,9) junk2 e f g h i -- (11,13,15) junk2 k l m n o -- (17,19,21) junk2 q r s t u 

    Было бы довольно просто добавить цвет, но было бы проще использовать grep (если это не предложит ничего желательного).

    1. Вам действительно нужен grep – вы используете регулярные выражения? fgrep быстрее.
    2. GNU grep имеет --mmap – согласно man-странице: «… В некоторых ситуациях – mmap дает лучшую производительность …» (но у него также есть некоторые проблемы, см. Справочную страницу).
    3. Просто сохраните файл: номера строк совпадающих строк и не повторите повторную grep – вам, конечно, не нужно делать это дважды, не так ли?
    Interesting Posts
    Linux и Unix - лучшая ОС в мире.