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

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

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

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 – вам, конечно, не нужно делать это дважды, не так ли?
  • Как запустить grep в одном столбце?
  • Поиск всех xml-файлов рекурсивно в каталоге для определенного тега и grep значение тега
  • Как извлечь подмаски из строки и записать их в файл?
  • как бороться с сложной иерархией?
  • Схемы Grep в выбранных строках
  • Как ускорить работу скрипта на основе поиска grep?
  • Трубопровод от grep до awk не работает
  • Тестирование регулярного выражения из stdin с помощью grep | sed | awk
  • Может кто-нибудь уточнить этот сценарий Bash
  • Как совместить начало / конец строки в регулярном выражении?
  • Как добавить / добавить временную метку для вывода grep?
  • PID PID некоторых процессов UNIX в ls -l
  • Linux и Unix - лучшая ОС в мире.