Я не впевнений:
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вихід на що-небудь, крім термінального пристрою, то grepss почне буферизацію їх виводу, що означає, що вихід цих greps, ймовірно, буде неправильно переплетений. Вам доведеться використовувати їх 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 {} +