Более быстрые альтернативы «найти» и «найти»?

28394
benhsu

Я хотел бы использовать «поиск» и «найти» для поиска исходных файлов в моем проекте, но они требуют много времени для запуска. Существуют ли более быстрые альтернативы этим программам, о которых я не знаю, или способы повышения производительности из этих программ?

15
`locate` уже должен быть достаточно быстрым, учитывая, что он использует предварительно созданный индекс (основное предостережение заключается в том, что его необходимо обновлять), в то время как` find` должен читать списки каталогов. afrazier 13 лет назад 2
Какой локацией вы пользуетесь? Mlocate намного быстрее, чем slocate (обратите внимание, что какой бы пакет вы ни установили, команда все еще находится, так что проверьте ваш менеджер пакетов) Paul 13 лет назад 2
@benhsu, когда я запускаю `find / usr / src -name fprintf.c` на моем настольном компьютере с OpenBSD, он возвращает расположение этих исходных файлов менее чем за 10 секунд. `найти fprintf.c | grep '^ / usr / src. * / fprintf.c $' `возвращается менее чем за секунду. Каково ваше определение «долго бежать» и как вы используете `find` и` locate`? Kusalananda 13 лет назад 0
@Paul, я использую mlocate. benhsu 13 лет назад 0
@ KAK, я хотел бы использовать вывод find / locate, чтобы открыть файл в emacs. Я имею в виду случай использования: я хочу отредактировать файл, я ввожу имя файла (или некоторое регулярное выражение, совпадающее с именем файла) в emacs, и emacs будет использовать find / locate для вызова списка файлов, соответствующих ему, поэтому мне понравится время отклика, достаточно быстрое, чтобы быть интерактивным (до 1 секунды). У меня есть около 3 миллионов файлов в $ HOME, и я могу сделать так, чтобы моя команда find удалила некоторые файлы. benhsu 13 лет назад 0

5 ответов на вопрос

14
RedGrittyBrick

Поиск исходных файлов в проекте

Используйте более простую команду

Как правило, исходный код проекта, вероятно, находится в одном месте, возможно, в нескольких подкаталогах, вложенных не более чем в две или три глубины, поэтому вы можете использовать (возможно) более быструю команду, такую ​​как

(cd /path/to/project; ls *.c */*.c */*/*.c) 

Используйте метаданные проекта

В C-проекте у вас обычно есть Makefile. В других проектах у вас может быть что-то подобное. Это может быть быстрым способом извлечения списка файлов (и их местоположения), написания скрипта, который использует эту информацию для поиска файлов. У меня есть «исходный» скрипт, чтобы я мог писать такие команды, как grep variable $(sources programname).

Ускорение найти

Ищите меньше мест, а не find / …используйте find /path/to/project …там, где это возможно. Упростите критерии выбора, насколько это возможно. Используйте конвейеры, чтобы отложить некоторые критерии выбора, если это более эффективно.

Также вы можете ограничить глубину поиска. Для меня это значительно повышает скорость поиска. Вы можете использовать ключ -maxdepth. Например, '-maxdepth 5'

Ускорение найти

Убедитесь, что он индексирует интересующие вас местоположения. Прочтите справочную страницу и используйте любые параметры, подходящие для вашей задачи.

 -U <dir> Create slocate database starting at path <dir>.  -d <path> --database=<path> Specifies the path of databases to search in.   -l <level> Security level. 0 turns security checks off. This will make searchs faster. 1 turns security checks on. This is the default. 

Убрать необходимость поиска

Может быть, вы ищете, потому что вы забыли, где что-то или не было сказано. В первом случае пишите заметки (документацию), во втором спрашивайте? Соглашения, стандарты и последовательность могут очень помочь.

8
benhsu

Я использовал часть «ускорения поиска» в ответе RedGrittyBrick. Я создал меньшую БД:

updatedb -o /home/benhsu/ben.db -U /home/benhsu/ -e "uninteresting/directory1 uninteresting/directory2" 

затем указал locateна это:locate -d /home/benhsu/ben.db

4
nobar

Тактика, которую я использую, заключается в применении -maxdepthопции с find:

find -maxdepth 1 -iname "*target*" 

Повторяйте с увеличением глубины, пока не найдете то, что ищете, или устали смотреть. Первые несколько итераций, вероятно, вернутся мгновенно.

Это гарантирует, что вы не тратите время впустую, просматривая глубины массивных поддеревьев, когда то, что вы ищете, с большей вероятностью будет находиться у основания иерархии.


Вот пример скрипта для автоматизации этого процесса (Ctrl-C, когда вы видите, что вы хотите):

( TARGET="*target*" for i in $(seq 1 9) ; do echo "=== search depth: $i" find -mindepth $i -maxdepth $i -iname "$TARGET" done echo "=== search depth: 10+" find -mindepth 10 -iname $TARGET ) 

Обратите внимание, что связанная с этим избыточность (каждый проход должен проходить через папки, обработанные в предыдущих проходах) будет в значительной степени оптимизирована за счет кэширования диска.

Почему findэтот порядок поиска не является встроенной функцией? Возможно, потому что это было бы сложно / невозможно реализовать, если вы предполагали, что избыточный обход недопустим. Наличие -depthопции намекает на возможность, но увы ...

... таким образом, выполняя поиск в ширину. nobar 8 лет назад 1
1
dannyw

Другое простое решение - использовать более новую расширенную оболочку. Включить:

  • bash: shopt -s globstar
  • ksh: set -o globstar
  • zsh: уже включен

Затем вы можете запустить такие команды в каталоге исходного кода верхнего уровня:

# grep through all c files grep printf **/*.c  # grep through all files grep printf ** 2>/dev/null 

Это имеет то преимущество, что он рекурсивно просматривает все подкаталоги и работает очень быстро.

0
Pablo Bianchi

Серебряный лучник

Возможно, вы найдете это полезным для очень быстрого поиска содержимого огромного количества файлов исходного кода. Просто введите ag <keyword>. Вот некоторые из моих выводов apt show silversearcher-ag:

  • Упаковка : silversearcher-ag
  • Сопровождающий : Хадзимэ Мизуно
  • Домашняя страница : https://github.com/ggreer/the_silver_searcher
  • Описание : очень быстрая grep-подобная программа, альтернатива ack-grep Silver Searcher - это grep-подобная программа, реализованная C. Попытка сделать что-то лучше, чем ack-grep. Он ищет шаблон примерно в 3–5 раз быстрее, чем ack-grep. Он игнорирует шаблоны файлов из ваших .gitignore и .hgignore.

screenshot

алгоритм [ripgrep's] (https://github.com/BurntSushi/ripgrep) предположительно работает быстрее, чем silversearch, и он также учитывает файлы `.gitignore` и пропускает` .git`, `.svn`,` .hg`. папки ccpizza 6 лет назад 1
@ccpizza Так? [Серебряный поисковик] (https://github.com/ggreer/the_silver_searcher) также учитывает `.gitignore` и по умолчанию игнорирует скрытые и двоичные файлы. Также есть больше участников, больше звезд на Github (14700 против 8300) и уже на репо мэров дистрибутивов. Пожалуйста, предоставьте обновленное сравнение достоверных сторонних источников. Тем не менее, `ripgrep` выглядит великолепным программным обеспечением. Pablo Bianchi 6 лет назад 0
хорошо знать! я никоим образом не связан с автором (ами) `ripgrep`, он просто соответствует моим требованиям, поэтому я перестал искать другие варианты. ccpizza 6 лет назад 0

Похожие вопросы