1

Я ищу инструмент, который будет быстрее, чем grep, может быть многопоточный grep, или что-то подобное ... Я смотрел на группу индексаторов, но я не продал, что мне нужен индекс ...

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

ie: grep -r 'exact match' > filepaths.log

Это около 4 ТБ данных, и я начал свой первый поиск 6 дней назад, и grep все еще работает. У меня есть еще дюжина поисков, и я не могу ждать 2 месяца, чтобы получить все эти имена файлов =]

Я рассмотрел следующее, однако, я не думаю, что мне нужны все навороты, с которыми идут эти индексаторы, мне просто нужно имя файла, где произошло совпадение ...

  • DTSearch
  • Терьер
  • Lucene
  • Xapian
  • отдача
  • сфинкс

и после долгих часов чтения обо всех этих двигателях у меня кружится голова, и мне бы хотелось, чтобы у меня был многопоточный grep lol, любые идеи и / или предложения очень ценятся!

PS: я использую CentOS 6.5

РЕДАКТИРОВАТЬ: Поиск многопоточных grep возвращает несколько элементов, мой вопрос, является ли многопоточный grep лучшим вариантом для того, что я делаю?

РЕДАКТИРОВАТЬ 2: После некоторой настройки, это то, что я придумал, и это идет намного быстрее, чем обычный grep, я все еще хотел бы, чтобы это было быстрее, хотя ... Я наблюдаю за моим диском в ожидании, и он еще не собирается, я могу сделать еще некоторые изменения, и def по-прежнему заинтересован в любых предложениях =]

find . -type f -print0 | xargs -0 -n10 -P4 grep -m 1 -H -l 'search string'

2 ответа2

10

grep связан с вводом / выводом, что означает, что его скорость определяется скоростью чтения файлов, которые он ищет. Несколько параллельных поисков могут конкурировать друг с другом за дисковый ввод-вывод, поэтому вы можете не заметить значительного ускорения.

Если вам просто нужны совпадающие имена файлов, а не фактические совпадения, найденные в файлах, тогда вы должны запустить grep с флагом -l . Этот флаг заставляет grep просто печатать имена файлов, которые совпадают, а не печатать совпадающие строки. Значение здесь в том, что он позволяет grep прекращать поиск файла после того, как он найдет совпадение, что может уменьшить объем работы, которую должен выполнить grep.

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

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

find /path/to/files -type f -print | split -l 10000000 list.
for file in list.*; do
    grep -f ${file} -l 'some text' > ${file}.out &
done
wait
cat $*.out > filepaths.log
rm list.*

Он использует команду find для поиска файлов, разбивает список имен файлов на группы по десять миллионов и запускает grep параллельно для каждой группы. Выходные данные greps все соединены вместе в конце. Это должно работать для файлов с типичными именами, но не будет работать для файлов, в которых, например, есть новые строки.

Другой подход использует xargs. Во-первых, вам нужно написать простой скрипт оболочки, который запускает grep в фоновом режиме:

#!/bin/bash
grep -l 'search text' "$@" >> grep.$$.out &

Это запустит grep в списке файлов, указанных в качестве аргументов скрипта, записав результат в файл с именем PID процесса. Процесс grep работает в фоновом режиме.

Тогда вы запустите скрипт так:

find /path/to/files -type f -print0 | xargs -0 -r /my/grep/script
[ wait for those to finish ]
cat grep.*.out > filepaths.log
rm grep.*.out

В этом случае xargs имена файлов в группы и запустит сценарий один раз для каждой группы. Скрипт запускает экземпляр grep один раз для каждой группы. После завершения всех экземпляров grep вы можете объединить их результаты. К сожалению, я не мог придумать умного способа автоматического ожидания завершения экземпляров grep, поэтому вам, возможно, придется сделать это вручную.

0

Похоже, вам нужен скрипт или небольшая программа, которая будет запускать несколько экземпляров (то есть 8 x grep могут быть запущены параллельно на современном i7 с 4 ядрами /8 нитями) из grep и объединять или объединять вывод, больше, чем вам нужен более быстрый grep ,

Как сделать такой сценарий - это совсем другой вопрос, но я бы так решил на вашу проблему.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .