Назад | Перейти на главную страницу

Найти файлы, содержащие строку, во всей файловой системе

Мне нужно найти все экземпляры данной строки во всей файловой системе, потому что я не помню, в какие файлы конфигурации, скрипт или какие-либо другие программы я ее поместил, и мне нужно обновить эту строку с помощью новой.

Я пробовал с помощью следующей команды

`grep -nr 'Needle' / --exclude-dir = .svn | mail myaddress@example.com -s 'Ссылки на xxx'

Если я запустил эту команду в небольшом каталоге, она даст мне нужный результат в виде

/path1/:nn:line containing needle
/path2/:nn:line containing needle

где / path1 - полный путь к файлу, nn - строка, содержащая иглу, а последнее поле - это содержимое строки.

Однако, когда я запускаю команду в корневом каталоге, процесс grep через некоторое время зависает. Я запускаю этот скрипт около 8 часов назад, и даже в небольшой файловой системе (менее 5 ГБ) он не заканчивается, и если я запускаю top или ps процесс кажется спящим

root 24909 0.0 0.1 3772 1520 pts/1 S+ Feb10 0:15 grep -nr needle / --exclude-dir=.svn

Почему это не заканчивается? Есть ли лучший способ сделать это (это одноразовая работа, мне не нужно выполнять ее более одного раза)

Спасибо.

Обновление: я нашел рабочее решение с find и xargs, которое, похоже, работает и использует меньше системных ресурсов, чем решение find -exec. Вот моя последняя командная строка:

find /{boot,etc,home,lib,lost+found,opt,root,sbin,usr,var} -type f -print0 | xargs -r0 grep -nr 'needle' | mail myaddress@example.com -s 'References on xxx'

Я использовал /{dir1,dir2,...,dirn} синтаксис, потому что мне нужны выходные строки с полным путем, включая ведущую косую черту, и таким образом вы можете использовать команду без cd / т.е. из любого каталога.

Вы можете попробовать использовать для этого find + xargs + grep, вроде:

find /there -type f :MaybeSomeRestrictingFlagsLikeSizeNotBigger500MB_or_FS_type_if_u_know_its_exactly_on_EXT3_AndSoOn: -print0 | xargs -0r grep needle /dev/null

(/ dev / null заставляет grep печатать имя файла, даже если был найден только один файл)

В файловой системе есть некоторые файлы, которые не являются настоящими файлами, а являются "перехватчиками" ядра. Некоторые из них можно читать бесконечно. Пытаться

grep foo /dev/zero

чтобы увидеть это в действии. Будьте готовы остановить его с помощью ctrl-C, прежде чем он возьмет на себя всю систему.

Если бы я хотел делать то, что делаете вы, я бы перечислил подкаталоги / которые я хотел просканировать, и убедитесь, что я проверял только текстовые файлы, возможно, с

cd /
find boot etc home lib lost+found media mnt opt root sbin tmp usr var -type f -exec grep needle {} /dev/null \;

Обратите внимание, как выглядит список не содержать /dev, /proc, /sys или /selinux.

Я не знаю, почему это не заканчивается, но в таких случаях обычно работает «fgrep -R».

Вы можете исключить dev и proc из этой команды. Я бы сделал это с помощью find и исключил специальные файлы:

find . -type f -exec grep -H "My search string" '{}' \; -print 

Как отмечали некоторые другие, ошибка возникает из-за того, что вы используете grep для некоторых «файлов», которые будут давать странные результаты. Например, grep XXX / dev / zero будет продолжаться вечно.

Сначала я бы исключил из поиска такие каталоги, как / dev / и / proc /. Другой способ - искать только «файлы» и никаких других типов.

Также, если ваш список аргументов в grep слишком длинный, вы получите эту ошибку:

bash: /bin/grep: Argument list too long

Вы можете обойти это с помощью цикла, например:

for i in `find -type f /`; do grep -H "sample string" $i; done

Или выполнив его из find, что бы ни плавало на вашей лодке.

find / -type f -exec grep -H "sample string" '{}' \; -print 

Это должно выполнить поиск, а затем grep для каждого файла. Хотя некоторые указали, что неэффективно запускать grep каждый раз, когда вы находите файл, вам придется делать что-то, что будет «неэффективным», потому что вам буквально придется искать эту строку в каждом файле.