Нечеткий поиск файлов в консоли Linux - PullRequest
40 голосов
/ 25 февраля 2012

Кто-нибудь знает способ выполнить быстрый нечеткий поиск из консоли Linux?

Довольно часто я сталкиваюсь с ситуацией, когда мне нужно найти файл в проекте, но я не помню точное имя файла. В Sublime текстовом редакторе я бы нажал Ctrl-P и набрал часть имени, чтобы получить список файлов для выбора. Это удивительная особенность, которой я вполне доволен. Проблема в том, что в большинстве случаев мне приходится просматривать код на консоли на удаленных машинах через ssh. Поэтому мне интересно, есть ли инструмент, похожий на функцию «Go Anywhere» для консоли Linux?

Ответы [ 11 ]

60 голосов
/ 06 ноября 2013

Вы можете найти fzf полезным.Это нечеткий искатель общего назначения, написанный на Go, который может использоваться с любым списком вещей: файлами, процессами, историей команд, ветками git и т. Д.

Его установочный скрипт установит CTRL-T привязку клавиш для вашей оболочки.Следующий GIF показывает, как это работает.

5 голосов
/ 30 января 2013

Сценарий fasd , вероятно, тоже стоит посмотреть.

fasd предлагает быстрый доступ к файлам и каталогам для оболочек POSIX. Он вдохновлен такими инструментами, как autojump, z и v. Fasd отслеживает файлы и каталоги, к которым вы обращались, чтобы вы могли быстро ссылаться на них в командной строке.

Он немного отличается от полного поиска всех файлов, так как он ищет только недавно открытых файлов. Однако это все еще очень полезно.

4 голосов
/ 15 ноября 2013

Большинство из этих ответов не будут выполнять нечеткий поиск, как это делает возвышенный текст - они могут совпадать с частью ответа, но они не выполняют функцию «просто найди все буквы в этом порядке».

Я думаю, это немного ближе к тому, что вы хотите. Я собрал специальную версию cd ('fcd'), которая использует нечеткий поиск, чтобы найти целевой каталог. Супер просто - просто добавьте это в ваш bashrc:

function joinstr { local IFS="$1"; shift; echo "$*"; }
function fcd { cd $(joinstr \* $(echo "$*" | fold -w1))* }

Это добавит * между каждой буквой на входе, поэтому, если я хочу перейти, например, к

/home/dave/results/sample/today

Я могу просто набрать любое из следующего:

fcd /h/d/r/spl/t
fcd /h/d/r/s/t
fcd /h/d/r/sam/t
fcd /h/d/r/s/ty

Используя первое в качестве примера, он выполнит cd /*h*/*d*/*r*/*s*p*l*/*t* и позволит оболочке отсортировать то, что действительно соответствует.

Пока первый символ правильный, и по одной букве из каждого каталога в пути написано, он найдет то, что вы ищете. Возможно, вы сможете адаптировать это для своих нужд? Важный бит:

$(joinstr \* $(echo "$*" | fold -w1))*

, которая создает нечеткую строку поиска.

3 голосов
/ 21 февраля 2014
find . -iname '*foo*'

Поиск файлов без учета регистра, содержащих foo.

3 голосов
/ 25 февраля 2012

Я обычно использую:

ls -R | grep  -i [whatever I can remember of the file name]

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

Когда я нахожу точное имя файла, я использую его в find:

find . [discovered file name]

Это можно свернуть в одну строку:

for f in $(ls --color=never -R | grep --color=never -i partialName); do find -name $f; done

(я обнаружил проблему с псевдонимом ls и grep для "--color = auto")

1 голос
/ 25 декабря 2018

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

enter image description here

Проект GitHub: whitebob / cminus

Введение на YouTube: https://youtu.be/b8Bem53Cz9A

1 голос
/ 07 марта 2018

fd - простая, быстрая и удобная альтернатива для поиска.

Демо со страницы проекта GitHub:

1 голос
/ 25 февраля 2012

Вы можете сделать следующее

grep -iR "text to search for" .

, где "."Будучи отправной точкой, вы можете сделать что-то вроде

grep -iR "text to search" /home/

Это позволит grep искать данный текст внутри каждого файла в / home / и списка файлов, содержащих этот текст.

1 голос
/ 25 февраля 2012

Я не знаю, насколько вы знакомы с терминалом, но это может вам помочь:

find | grep 'report'
find | grep 'report.*2008'

Извините, если вы уже знаете grep и искали что-то более продвинутое.

0 голосов
/ 25 февраля 2012

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

find . -type f -regextype posix-extended -iregex ".*YOUR_PARTIAL_NAME.*" -print

Или это для более простых глобальных матчей:

find . -type f -name "*YOUR_PARTIAL_NAME*" -print

Или вы также можете использовать find2perl (который гораздо быстрее и более оптимизирован, чем find), например:

find2perl . -type f -name "*YOUR_PARTIAL_NAME*" -print | perl

Если вы просто хотите посмотреть, как это делает Perl, удалите часть | perl, и вы увидите код, который она генерирует. Кстати, это очень хороший способ учиться.

В качестве альтернативы, напишите оболочку быстрого bash, как это, и вызывайте ее, когда хотите:

#! /bin/bash
FIND_BASE="$1"
GLOB_PATTERN="$2"
if [ $# -ne 2 ]; then
    echo "Syntax: $(basename $0) <FIND_BASE> <GLOB_PATTERN>"
else
        find2perl "$FIND_BASE" -type f -name "*$GLOB_PATTERN*" -print | perl
fi

Назовите это как-то как qsearch, а затем назовите это так: qsearch . something

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...