У меня есть папка с 250+ файлами по 2 ГБ каждый. Мне нужно найти строку / шаблон в этих файлах и вывести результат в output
файл. Я знаю, что могу выполнить следующую команду, но она слишком медленная !!
grep mypattern * > output
Я хочу ускорить это. Будучи программистом на Java, я знаю, что многопоточность может быть использована для ускорения процесса. Я застрял на том, как начать grep
в «многопоточном режиме» и записать вывод в один output
файл.
grep
parallelism
Абхишек
источник
источник
Ответы:
Для этого есть два простых решения. В основном, используя
xargs
илиparallel
.XARGS подход:
Вы можете использовать
xargs
сfind
следующим:Где вы замените
number_of_processes
максимальное количество процессов, которые вы хотите запустить. Однако это не гарантирует значительную производительность в случае, если ваша производительность ограничена вводом / выводом. В этом случае вы можете попытаться запустить больше процессов, чтобы компенсировать потерянное время ожидания ввода-вывода.Кроме того, с помощью поиска можно указать более сложные параметры, а не только шаблоны файлов, такие как время модификации и т. Д.
Одна возможная проблема с этим подходом, как объяснено комментариями Стефана, если файлов мало,
xargs
может не запустить достаточно много процессов для них. Одним из решений будет использование-n
опции дляxargs
указания количества аргументов, которые он должен принимать из канала за раз. Установка-n1
заставитxargs
начать новый процесс для каждого отдельного файла. Это может быть желательным поведением, если файлы очень велики (как в случае с этим вопросом) и существует относительно небольшое количество файлов. Однако если сами файлы небольшие, накладные расходы на запуск нового процесса могут подорвать преимущество параллелизма, и в этом случае большее-n
значение будет лучше. Таким образом,-n
опция может быть точно настроена в соответствии с размерами и количеством файлов.Параллельный подход:
Другой способ сделать это - использовать инструмент Ole Tange GNU Parallel
parallel
(доступен здесь ). Это обеспечивает больший контроль над параллелизмом и даже может быть распределен по нескольким хостам (было бы полезно, например, если ваш каталог используется совместно). Простейший синтаксис с использованием параллельного будет:find . -type f | parallel -j+1 grep mypattern
где опция
-j+1
указывает параллельно запускать один процесс сверх количества ядер на вашем компьютере (это может быть полезно для задач с ограниченным вводом / выводом, вы можете даже попытаться увеличить их количество).Параллель также имеет преимущество перед
xargs
фактическим сохранением порядка вывода из каждого процесса и генерацией непрерывного вывода. Например,xargs
если, если процесс 1 генерирует строку, скажемp1L1
, процесс 2 генерирует строкуp2L1
, процесс 1 генерирует другую строкуp1L2
, вывод будет:тогда как с
parallel
выводом должно быть:Это обычно более полезно, чем
xargs
вывод.источник
-n
в сочетании с-P
. Иначе,xargs
может не закончиться порождением нескольких процессов, если есть два файла.grep
на файл. Если файлы не очень большие и их очень мало, вы, вероятно, захотите увеличить их немного, потратив время на запуск и остановку процессов grep вместо поиска в файлах.Существует по крайней мере два способа ускорения работы процессора с помощью grep:
Если вы ищете фиксированную строку, а не регулярное выражение, укажите
-F
флаг;Если ваш шаблон только для ASCII, используйте 8-битный языковой стандарт вместо UTF-8, например
LC_ALL=C grep ...
.Это не поможет, если ваш жесткий диск является узким местом; в этом случае, вероятно, распараллеливание тоже не поможет.
источник
man grep
«Прямом вызове указано, что egrep или fgrep устарели, но он позволяет историческим приложениям, которые полагаются на них, работать без изменений». Не уверен, что это действительно имеет значение, но это то же самое, чтоgrep -F
Если проблема не связана с вводом / выводом, вы можете использовать инструмент, оптимизированный для многоядерной обработки.
Возможно, вы захотите взглянуть на sift ( http://sift-tool.org , заявление об отказе: я автор этого инструмента) или поисковик серебра ( https://github.com/ggreer/the_silver_searcher ).
Серебряный искатель имеет ограничение размера файла 2 ГБ, если вы используете шаблон регулярных выражений, а не поиск по строчкам.
источник