Я не впевнений:
grep -r -i 'the brown dog' /*
це дійсно те, що ви мали на увазі. Це означає, що греп рекурсивно у всіх не прихованих файлах і dirs /
(але все ж заглядайте всередині прихованих файлів та dirs всередині цих).
Якщо припустити, що ви мали на увазі:
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
вихід на що-небудь, крім термінального пристрою, то greps
s почне буферизацію їх виводу, що означає, що вихід цих grep
s, ймовірно, буде неправильно переплетений. Вам доведеться використовувати їх stdbuf -oL
(якщо вони доступні, як у GNU або FreeBSD), щоб обійти це (у вас все ще можуть виникнути проблеми з дуже довгими рядками (як правило,> 4KiB)) або записати свої результати в окремий файл і об'єднати їх. все врешті-решт.
Тут ви шукаєте рядок, який ви шукаєте, виправлений (а не регулярний вираз), тому використання -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 {} +