У меня есть каталог с около 26 000 файлов, и мне нужно grep во всех этих файлах. Проблема в том, что мне это нужно как можно быстрее, поэтому не идеально делать скрипт, в котором grep будет брать имя одного файла из команды поиска и записывать совпадения в файл. Прежде чем "список аргументов слишком длинный", потребовалось около 2 минут, чтобы собрать все эти файлы. Есть идеи как это сделать? edit: есть скрипт, который постоянно создает новые файлы, поэтому невозможно поместить все файлы в разные каталоги.
files
grep
performance
user2778979
источник
источник
find
сxargs
илиgrep -R
Ответы:
С
find
:(
-type f
это поиск только в обычных файлах (также исключая символические ссылки, даже если они указывают на обычные файлы). Если вы хотите искать в любом типе файлов, кроме каталогов (но будьте осторожны, есть некоторые типы файлов, такие как fifos или / dev / zero, которые как правило, вы не хотите читать), замените его-type f
на GNU-специфичный! -xtype d
(-xtype d
соответствует файлам типа directory после разрешения символической ссылки)).С GNU
grep
:(но учтите, что если у вас нет последней версии GNU grep, она будет следовать символическим ссылкам при переходе в каталоги). Нестандартные файлы не будут искать, если вы не добавите
-D read
опцию. Последние версии GNUgrep
все равно не будут искать внутри символических ссылок.Очень старые версии GNU
find
не поддерживают стандартный{} +
синтаксис, но там вы можете использовать нестандартный:Представления могут быть связаны с вводом / выводом. Это время для поиска будет временем, необходимым для чтения всех этих данных из хранилища.
Если данные находятся на избыточном дисковом массиве, чтение нескольких файлов за один раз может повысить производительность (и в противном случае их можно ухудшить). Если производительность не связана с вводом / выводом (потому что, например, все данные находятся в кеше), и у вас есть несколько процессоров, параллельная работа также
greps
может помочь. Вы можете сделать это с помощью GNUxargs
«s-P
варианта.Например, если данные находятся в массиве RAID1 с 3 дисками или если данные находятся в кеше, и у вас есть 3 ЦП, время которых можно сэкономить:
(здесь используется,
-n1000
чтобы порождать новыеgrep
каждые 1000 файлов, до 3 параллельно работающих одновременно).Однако обратите внимание, что если выходные данные
grep
перенаправлены, вы получите плохо чередующиеся выходные данные 3grep
процессов, и в этом случае вы можете запустить его как:(в недавней системе GNU или FreeBSD) или используйте
--line-buffered
опцию GNUgrep
.Если
pattern
это фиксированная строка, добавление-F
опции может улучшить ситуацию.Если это не многобайтовые символьные данные или если для сопоставления с этим шаблоном не имеет значения, являются ли данные многобайтовыми символами или нет, тогда:
может значительно улучшить производительность.
Если вам приходится часто выполнять такие поиски, вы можете проиндексировать свои данные с помощью одной из многочисленных поисковых систем.
источник
26000 файлов в одном каталоге - это много для большинства файловых систем. Вероятно, значительная часть времени уходит на чтение этого большого каталога. Подумайте о том, чтобы разбить его на более мелкие каталоги с несколькими сотнями файлов в каждом.
Вызов
find
не может объяснить плохую производительность, если вы не сделаете это неправильно. Это быстрый способ обхода каталога и гарантии того, что вы не рискуете выполнить слишком длинную командную строку. Убедитесь, что вы используете-exec grep PATTERN {} +
, который упаковывает столько файлов, сколько может для вызова команды, а не-exec grep PATTERN {} \;
, который выполняетсяgrep
один раз для файла: выполнение команды один раз для файла, вероятно, будет значительно медленнее.источник
Если вам нужно выполнить grep ВСЕХ файлов несколько раз (как вы сказали, запустив скрипт), я бы посоветовал посмотреть на ram-диски, скопировать все файлы туда, а затем grep файлы несколько раз, это ускорит ваш поиск в несколько раз. по крайней мере, 100x.
Вам просто нужно достаточно барана. Иначе, вы должны посмотреть на индексацию файлов, например. в базу данных lucene или nosql, а затем запускает запросы к ним.
источник
grep
. Также есть смысл: «Существует скрипт, который постоянно создает новые файлы, поэтому невозможно поместить все файлы в разные каталоги».Все файлы в каталоге
с рекурсивно
источник
.
вместо*
).*
исключит точечные файлы (хотя с -R, а не в рекурсивных каталогах). -R в отличие от -r следует символическим ссылкам даже в последних версиях GNU grep. У вас также будет проблема с файлами в текущем каталоге, имя которых начинается с-