Нечеткий поиск файлов в консоли Linux
Кто-нибудь знает способ выполнить быстрый нечеткий поиск из консоли Linux?
Довольно часто я сталкиваюсь с ситуацией, когда мне нужно найти файл в проекте, но я не помню точное имя файла. В текстовом редакторе Sublime я бы нажимал Ctrl-P и вводил часть имени, чтобы получить список файлов для выбора. Это удивительная особенность, которой я вполне доволен. Проблема в том, что в большинстве случаев мне приходится просматривать код в консоли на удаленных машинах через ssh. Поэтому мне интересно, есть ли инструмент, похожий на функцию "Go Anywhere" для консоли Linux?
12 ответов
Вы можете найти FZF полезным. Это нечеткий искатель общего назначения, написанный на Go, который можно использовать с любым списком вещей: файлы, процессы, история команд, ветки git и т. Д.
Его установочный скрипт установит CTRL-T
связывание клавиш для вашей оболочки. Следующий GIF показывает, как это работает.
Большинство из этих ответов не будут выполнять нечеткий поиск, как это делает возвышенный текст - они могут совпадать с частью ответа, но они не выполняют функцию "просто найди все буквы в этом порядке".
Я думаю, что это немного ближе к тому, что вы хотите. Я собрал специальную версию 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))*
который создает нечеткую строку поиска.
Вероятно, стоит взглянуть и на скрипт оболочки fasd.
fasd
предлагает быстрый доступ к файлам и каталогам для оболочек POSIX. Он вдохновлен такими инструментами, как autojump, z и v. Fasd отслеживает файлы и каталоги, к которым вы обращались, так что вы можете быстро ссылаться на них в командной строке.
Он немного отличается от полного поиска всех файлов, так как он ищет только недавно открытые файлы. Однако это все еще очень полезно.
find . -iname '*foo*'
Нечувствительный к регистру поиск имен файлов, содержащих foo
,
Я обычно использую:
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")
Я не знаю, насколько вы знакомы с терминалом, но это может помочь вам:
find | grep 'report'
find | grep 'report.*2008'
Извините если вы уже знаете grep
и искали что-то более продвинутое.
Вы можете попробовать c- ( Cminus), инструмент нечеткого изменения директорий bash-скрипта, который использует bash завершение. Это как-то ограничено только сопоставлением посещенных путей, но действительно удобно и довольно быстро.
Проект GitHub: https://github.com/whitebob/cminus
Введение в YouTube: https://youtu.be/b8Bem53Cz9A
Вы можете сделать следующее
grep -iR "text to search for" .
где "." быть отправной точкой, так что вы могли бы сделать что-то вроде
grep -iR "text to search" /home/
Это заставит grep искать заданный текст внутри каждого файла в /home/ и перечислять файлы, которые содержат этот текст.
Вы можете использовать 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
Найдите zsh для файла или папки в терминале и откройте или перейдите к нему с помощью комбинации find , fzf , vim и cd .
Установите fzf в zsh и добавьте скрипт в
~/.zshrc
, затем перезагрузите снаряд
source ~/.zshrc
fzf-file-search() {
item="$(find '/' -type d \( -path '/proc/*' -o -path '/dev/*' \) -prune -false -o -iname '*' 2>/dev/null | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --rev erse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_CTRL_T_OPTS" $(__fzfcmd) -m "$@")"
if [[ -d ${item} ]]; then
cd "${item}" || return 1
elif [[ -f ${item} ]]; then
(vi "${item}" < /dev/tty) || return 1
else
return 1
fi
zle accept-line
}
zle -N fzf-file-search
bindkey '^f' fzf-file-search
Нажмите сочетание клавиш
'Ctrl+F'
чтобы запустить его, это можно изменить в
bindkey '^f'
. Он выполняет поиск ( находит ) во всех файлах / папках ( fzf ) и, в зависимости от типа файла, переходит в каталог ( cd ) или открывает файл с помощью текстового редактора ( vim ).
Также быстро открывайте недавние файлы / папки с помощью fasd:
fasd-fzf-cd-vi() {
item="$(fasd -Rl "$1" | fzf -1 -0 --no-sort +m)"
if [[ -d ${item} ]]; then
cd "${item}" || return 1
elif [[ -f ${item} ]]; then
(vi "${item}" < /dev/tty) || return 1
else
return 1
fi
zle accept-line
}
zle -N fasd-fzf-cd-vi
bindkey '^e' fasd-fzf-cd-vi
Сочетание клавиш
'Ctrl+E'
Ознакомьтесь с другими полезными советами и рекомендациями по быстрой навигации внутри терминала https://github.com/webdev4422/.dotfiles