grep -R(за исключением модифицированного GNU, grepнайденного в OS / X 10.8 и выше), следует ~/Documentsсимвольные ссылки , поэтому, даже если в нем всего 100 ГБ файлов , может существовать символическая ссылка, /например, и вы в конечном итоге сканируете всю файловую систему, включая файлы как /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 grep2.6