Я не уверен:
grep -r -i 'the brown dog' /*
действительно то, что вы имели в виду. Это будет означать рекурсивный grep во всех не скрытых файлах и директориях /(но все же заглянуть внутрь скрытых файлов и каталогов внутри них).
Предполагая, что вы имели в виду:
grep -r -i 'the brown dog' /
Несколько вещей, на которые стоит обратить внимание:
- Не все
grepреализации поддерживают -r. И среди тех, кто это делает, поведение отличается: некоторые переходят по символическим ссылкам на каталоги при обходе дерева каталогов (что означает, что вы можете в конечном итоге просмотреть один и тот же файл несколько раз или даже выполнить бесконечные циклы), некоторые - нет. Некоторые будут смотреть внутри файлов устройств (и это займет довольно много времени, /dev/zeroнапример) или каналов или двоичных файлов ..., некоторые не будут.
- Это эффективно, так как
grepначинает искать внутри файлов, как только обнаруживает их. Но пока он просматривает файл, он больше не ищет больше файлов для поиска (что, вероятно, также хорошо в большинстве случаев)
Твой:
find / -type f -exec grep -i 'the brown dog' {} \;
(убрал то, -rчто здесь не имело смысла) ужасно неэффективно, потому что вы запускаете по одному grepна файл. ;следует использовать только для команд, которые принимают только один аргумент. Более того, здесь, поскольку grepвыглядит только в одном файле, он не будет печатать имя файла, поэтому вы не будете знать, где находятся совпадения.
Вы не заглядывая внутрь файлы устройства, трубы, симлинки ..., вы не следующие ссылок, но вы по- прежнему потенциально смотрите внутри вещи , как /proc/mem.
find / -type f -exec grep -i 'the brown dog' {} +
было бы намного лучше, потому что grepбыло бы выполнено как можно меньше команд. Вы получите имя файла, если только у последнего запуска не будет только одного файла. Для этого лучше использовать:
find / -type f -exec grep -i 'the brown dog' /dev/null {} +
или с GNU grep:
find / -type f -exec grep -Hi 'the brown dog' {} +
Обратите внимание, что grepон не будет запущен, пока findне найдет достаточно файлов для его пережевывания, поэтому будет некоторая начальная задержка. И findне будет продолжать поиск других файлов, пока grepне вернется предыдущий . Распределение и передача большого списка файлов оказывает некоторое (вероятно, незначительное) влияние, поэтому в целом он, вероятно, будет менее эффективным, чем grep -rтот, который не следует по символической ссылке или не заглядывает внутрь устройств.
С инструментами GNU:
find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'
Как и выше, grepбудет запущено как можно меньше экземпляров, но findбудет продолжаться поиск большего количества файлов, пока первый grepвызов просматривает первый пакет. Это может или не может быть преимуществом, хотя. Например, данные, хранящиеся на вращающихся жестких дисках, findи grepдоступ к данным, хранящимся в разных местах на диске, замедляют пропускную способность диска, вызывая постоянное перемещение головки диска. В настройке RAID (где findи grepмогут иметься доступ к разным дискам) или на SSD это может иметь положительное значение.
В настройке RAID выполнение нескольких одновременных grep вызовов также может улучшить ситуацию. Все еще с инструментами GNU на хранилище RAID1 с 3 дисками,
find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'
может значительно увеличить производительность. Однако обратите внимание, что вторая grepбудет запущена только после того, как будет найдено достаточно файлов для заполнения первой grepкоманды. Вы можете добавить -nопцию xargsдля того, чтобы это произошло раньше (и передавать меньше файлов за grepвызов).
Также обратите внимание, что если вы перенаправляете xargsвывод на что-либо, кроме оконечного устройства, то grepss начнут буферизовать свои выходные данные, что означает, что выходные данные этих greps будут, вероятно, неправильно чередоваться. Вам придется использовать stdbuf -oL(там, где это доступно, например, в GNU или FreeBSD) их, чтобы обойти это (у вас все еще могут быть проблемы с очень длинными строками (обычно> 4 КБ)) или каждый из них записывает свои выходные данные в отдельный файл и объединяет их все в итоге.
Здесь искомая строка является фиксированной (не является регулярным выражением), поэтому использование -Fопции может иметь значение (маловероятно, поскольку grepреализации уже знают, как ее оптимизировать).
Еще одна вещь, которая может иметь большое значение, это исправить языковой стандарт на C, если вы находитесь в многобайтовом языковом стандарте:
find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'
Чтобы не заглядывать внутрь /proc, /sys... используйте -xdevи укажите файловые системы, в которых вы хотите искать:
LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +
Или удалите пути, которые вы хотите явно исключить:
LC_ALL=C find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o \
-type f -exec grep -i 'the brown dog' /dev/null {} +