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 $ -l 'some text' > $.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, поэтому вам, возможно, придется сделать это вручную.