grep -R
(за винятком модифікованого GNU, grep
знайденого в OS / X 10.8 і вище), слід за символьними посиланнями, тому навіть якщо в ньому є лише 100 ГБ файлів ~/Documents
, можливо, все-таки буде посилання на, /
наприклад, і ви закінчите сканувати всю файлову систему, включаючи файли як /dev/zero
. Використовуйте grep -r
з новішими GNU grep
або використовуйте стандартний синтаксис:
find ~/Documents -type f -exec grep Milledgeville /dev/null {} +
(проте зауважте, що статус виходу не відображатиме факту відповідності шаблону чи ні).
grep
знаходить лінії, що відповідають візерунку. Для цього він повинен завантажувати по одному рядку по черзі в пам'ять. GNU grep
на відміну від багатьох інших grep
реалізацій не обмежує розмір рядків, які він читає, і підтримує пошук у бінарних файлах. Отже, якщо у вас є файл із дуже великою лінією (тобто з двома символами нового рядка, далеко більшими за наявну пам'ять), він вийде з ладу.
Зазвичай це відбувається з розрідженим файлом. Ви можете відтворити його за допомогою:
truncate -s200G some-file
grep foo some-file
З цим важко обійтись. Ви можете це зробити так само (як і раніше в GNU grep
):
find ~/Documents -type f -exec sh -c 'for i do
tr -s "\0" "\n" < "$i" | grep --label="$i" -He "$0"
done' Milledgeville {} +
Це перетворює послідовності символів NUL в один символ нового рядка перед подачею на вхід grep
. Це охоплює випадки, коли проблема пов’язана з розрідженими файлами.
Ви можете оптимізувати це, зробивши це лише для великих файлів:
find ~/Documents -type f \( -size -100M -exec \
grep -He Milledgeville {} + -o -exec sh -c 'for i do
tr -s "\0" "\n" < "$i" | grep --label="$i" -He "$0"
done' Milledgeville {} + \)
Якщо файли не надто рідкі і у вас є версія GNU grep
до цього 2.6
, ви можете скористатися цією --mmap
опцією. Рядки будуть мапані в пам'ять на відміну від скопійованих туди, а це означає, що система завжди може повернути пам'ять, додавши сторінки у файл. Цей варіант було видалено в GNU grep
2.6