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 grep
2.6