Вопрос или проблема
Существует ли что-то похожее на обратный поиск истории команд bash (Ctrl–R), но только для директорий?
У меня есть некоторые глубокие иерархии папок, в которые я хочу перемещаться, поэтому мне хотелось бы использовать что-то вроде обратного поиска истории, но это только ищет имена папок и дает мне абсолютные пути.
По сути, это давало бы аналогичные результаты, как использование !?
, но только соответствующие командам с cd
впереди, вы можете просматривать результаты и получать полные пути.
На данный момент лучший найденный мной решением является bashmarks.
Посмотрите на autojump:
Одна из самых часто используемых команд оболочки – “cd”. Быстрый опрос среди моих друзей показал, что от 10 до 20% всех введенных ими команд на самом деле являются командами cd! К сожалению, переход от одной части системы к другой с помощью cd требует ввода почти полного пути, что не очень удобно и требует много нажатий клавиш.
autojump – это более быстрый способ навигации по вашей файловой системе. Он работает, поддерживая базу данных директорий, которые вы используете чаще всего из командной строки. Команда jumpstat показывает текущее содержимое базы данных. Вам нужно немного поработать, прежде чем база данных станет полезной. Как только ваша база данных будет достаточно полной, вы сможете “прыгать” в часто используемую директорию, напечатав:
j dirspec
Существует
cd -
это команда “cd[пробел][дефис]”, которая перемещает вас в директорию, в которой вы были до этого, по сути это “история глубины 1”. Повторное использование “cd -” переключает между двумя директориями.
Цитируя страницу man:
Следующие операнды будут поддерживаться: […]
Когда [дефис] используется в качестве операнда, это будет эквивалентно команде:
cd "$OLDPWD" && pwd
К сожалению, я не знаю о реальной встроенной истории директорий.
Вы можете создать собственную команду cd
с использованием pushd
, popd
, dirs
встроенных команд.
Использование
-
cd --
( показать текущую историю ) -
cd -num
( перейти в num директорию ) -
cd -
( перейти в предыдущую директорию )
function cd ()
{
local hnum=16;
local new_dir index dir cnt;
if ! [ $# -eq 0 ]; then
if [[ $# -eq 2 && $1 = "--" ]]; then
shift;
else
if ! {
[ $# -eq 1 ] && [[ $1 =~ ^(-[0-9]{,2}|-|--|[^-].*)$ ]]
}; then
builtin cd "$@";
return;
fi;
fi;
fi;
[ "$1" = "--" ] && {
dirs -v;
return
};
new_dir=${1:-$HOME};
if [[ "$new_dir" =~ ^-[0-9]{,2}$ ]]; then
index=${new_dir:1};
if [ -z "$index" ]; then
new_dir=$OLDPWD;
else
new_dir=$(dirs -l +$index) || return;
fi;
fi;
pushd -- "$new_dir" > /dev/null || return;
popd -n +$hnum &> /dev/null || true;
new_dir=$PWD cnt=1;
while dir=$(dirs -l +$cnt 2> /dev/null); do
if [ "$dir" = "$new_dir" ]; then
popd -n +$cnt > /dev/null;
continue;
fi;
let cnt++;
done
}
bash имеет команды pushd/popd/dirs.
У меня это в моем .bashrc, чтобы автоматически добавлять директории в стек bash.
#позволить cd также добавлять директории в стек. Используйте popd для убирать из стека
function cd ()
{
if [ -e $1 ]; then
pushd $1 &> /dev/null #не отображать текущий стек
fi
}
Извлекайте их с помощью popd
и отображайте стек с помощью dirs
Я сделал скрипт, который имеет аналогичный функционал команде oh-my-zsh dirs -v
, которая работает в bash. Если вы когда-либо использовали oh-my-zsh, вы могли заметить, что история директорий, предоставленная командой dirs -v
, будет сбрасываться каждый раз, когда вы выходите из терминала. Это не произойдет, если вы используете этот скрипт.
Функциональность:
-
Показать список из 10 недавно использованных директорий с помощью
d
. -
Перейти в любую директорию из списка, напечатав номер директории в списке.
-
Путь к директории будет помещаться в верхнюю часть списка каждый раз, когда вы посещаете директорию.
Просто чтобы поделиться своим опытом, я написал простой скрипт, чтобы решить эту задачу некоторое время назад, он переопределяет встроенную команду cd с помощью простой функции, которая добавляет новое местоположение директории в файл истории, затем используется python скрипт для предоставления интерфейса bash, который динамически обновляет упорядоченный список директорий при вводе вами поисковых запросов, что-то вроде обратного поиска команд bash.
Он доступен на git-hub для тех, кто интересуется.
Я хотел бы порекомендовать свой ltcd
для быстрого навигации по истории директорий:
Он предоставляет следующие функции для упрощения жизни:
- Глобальный список директорий, который показывает недавно посещенные директории из всех вкладок/окон терминала.
- Локальный список директорий, который локален для текущей сессии оболочки.
- Оба списка поддерживают быструю навигацию с помощью j/k (перемещение вниз/вверх), цифр и поиска по словам.
- Глобальный свободный переход (например, “cd dir” или “cd ar”, чтобы перейти к /path/to/foo/bar/directory/).
У меня был хороший опыт с z-jump. Он позволяет завершение, хотя только для конечного назначения, а не для прохождения по пути. Тем не менее, он показывает полный путь при завершении с помощью табуляции.
Я написал свой собственный cdhist
инструмент для этого примерно 15 лет назад и использую его каждый день с тех пор. Он заменяет вашу команду cd
на псевдоним, который отслеживает директории, которые вы посещаете, чтобы вы могли cd --
для их отображения и затем выбрать одну из них. Он также интегрируется с fzf
, если вам больше нравится нечеткий поиск по ранее посещенным директориям.
Чистая реализация Bash для меню постоянной истории директорий:
#
# ~/.bash_profile
#
cdHistoryFile=~/.bash_cdhistory
cd() {
builtin cd $@ && echo $PWD >> $cdHistoryFile
}
cdh() {
local IFS=$'\n'
local directories=()
for line in `tac $cdHistoryFile`; do directories+=($line); done
cnt=${#directories[@]}
for ((i = 0; i < cnt - 1; i++)) {
for ((j = i + 1; j < cnt; j++)) {
[ "${directories[$i]}" == "${directories[$j]}" ] && unset directories[$j]
}
}
directories=("${directories[@]:1:${1:-15}}")
local select=0 subset=("${directories[@]}")
until [ $select -eq 1 ]; do
select dir in ${subset[@]}; do
case $REPLY in
q) select=1; break ;;
\.) subset=("${directories[@]}"); break ;;
.*) subset=($(printf '%s\n' "${subset[@]}" | egrep "${REPLY:1}")); break ;;
*) cd $dir; select=1; break
esac
done
done
}
Объяснение:
cd()
оборачивает встроенную команду cd
с помощью функции, которая записывает изменения директорий в файл. cdh()
отображает меню выбора последних уникальных директорий (в порядке убывания от наиболее недавно использованных).
Использование:
cdhistory: cdh [n]
Опции:
n Получить последнее количество уникальных директорий [по умолчанию: 15]
Выбор:
q Выход
. Показать оригинальный список
.<regex> Отфильтровать текущий список
# Изменить директорию
Пример:
[jdoe@localhost /] $ . ~/.bash_profile && cdh
1) /home/jdoe/tmp/2/3/1
2) /home/jdoe/tmp/3
3) /home/jdoe/code/projects
4) /home/jdoe/tmp/2
5) /home/jdoe/code/projects/cloud/pipeline
6) /home/jdoe/tmp/1
7) /
8) /etc
9) /usr/etc
10) /usr/share/libtool
11) /home/jdoe/tmp
#? .tmp
1) /home/jdoe/tmp/2/3/1 3) /home/jdoe/tmp/2 5) /home/jdoe/tmp
2) /home/jdoe/tmp/3 4) /home/jdoe/tmp/1
#? .3
1) /home/jdoe/tmp/2/3/1
2) /home/jdoe/tmp/3
#? 2
[jdoe@localhost /home/jdoe/tmp/3] $
Я предложу еще одно решение: нечеткий поиск по пути
-
После того, как вы запустите его в фоновом режиме, вы можете нажать Alt+C, чтобы открыть окно, где вы можете ввести нечеткую строку для поиска директорий. После того как вы выберете одну и нажмете Enter, fzf переключится на эту директорию.
Смотрите также
Существуют также различные оболочки и расширения оболочек, которые поддерживают частичное автозаполнение путей, и fish одна из них
Например cd /v/l/fsck
Tab преобразует путь в /var/log/fsck/
. cd /u/s/appl
Tab расширяет путь до /usr/share/applications/
Попробуйте WCD, который является заменой cd
, хранящей список директорий, в которые вы вошли. Это именно список истории директорий, который вы можете просмотреть с помощью любых текстовых редакторов.
Запуск wcd foo
покажет список директорий, содержащих foo, и вы можете выбрать одну из них, чтобы прыгнуть в нее.
Wcd
– это программа командной строки для быстрого изменения директорий. Она экономит время, не заставляя вас набирать на клавиатуре. Нужно ввести только часть имени директории, иwcd
прыгнет в нее.Wcd
имеет быстрый метод выбора в случае множества совпадений и позволяет создавать псевдонимы и запрещать директории.Wcd
также включает полноэкранный интерактивный браузер деревьев директорий с быстрым поиском.
Wcd
был смоделирован по образцу Norton Change Directory (NCD). NCD впервые появился в The Norton Utilities, Release 4, для DOS в 1987 году, опубликованном Петером Нортоном. NCD написан Брэдом Кингсбери.Примеры использования wcd:
wcd Desk
перейдет в директорию
/home/waterlan/Desktop
Но также
wcd *top
сработает.
вот еще одна реализация, история и также использование locate: https://github.com/joknarf/cdhist (совместим с оболочками ksh / bash / zsh / ash на linux* / macos / ish / msys2 / solaris…)
Итак, вы можете добавить этот фрагмент кода в ваш ~/.bashrc
, который
-
предоставляет пользовательскую команду cd
function cd () { exists=false for dir in "${CDHIST[@]}"; do [ "$dir" == "$1" ] && { exists == true break } done $exists || { len=${#CDHIST[@]} ${CDHIST[$len]} = "$1" } builtin cd "$1" }
-
и предоставляет команду поиска истории cd.
function cdhist () { #TODO: Сделать это волшебным. for dir in "${CDHIST[@]}"; do echo "$dir" done }
Конечно, команда cdhist, которую я предоставил, очень базовая и не то, что вам нужно; но можно рассмотреть использование операторов выбора или расширения параметров, чтобы добиться чего-то подобного тому, что вы хотите.
Вы даже можете добавить функцию “Программируемое автозавершение”, которая могла бы использоваться для добавления полной команды cd /path/to/mydir
на основе уникальной подстроки /path/to/unique/mydir
, хотя этот метод все равно потребует от вас ввести cd unique/mydir<tab>
.
Я собрал этот инструмент, который объединяет предыдущие решения для хранения комплексной глобальной истории CLI с интерактивным инструментом grep под названием percol (сопоставленным с C^R
). Я использую его для извлечения команд по тому, где они были выполнены, или для поиска директории по команде. Он по-прежнему работает быстро на первом компьютере, на котором я начал его использовать, теперь с историей CLI более 2 лет.
Инструмент grep работает как с путями, так и с командами, но может быть полезен вам. Смотрите также dirs -v
в zsh.
Ответ или решение
История каталогов в Bash: Обзор доступных решений
Bash, как популярная командная оболочка, предлагает множество возможностей для управления файлами и каталогами. Однако у многих пользователей возникает вопрос: Существует ли аналог истории команд для каталогов в Bash? Ниже мы рассмотрим несколько подходов к этой проблеме, включая встроенные команды, такие как pushd
и popd
, а также сторонние инструменты и сценарии.
1. Встроенные команды: cd
, pushd
, popd
Bash предоставляет несколько встроенных команд, которые можно использовать для управления историей каталогов:
-
cd -
: Эта команда позволяет вам быстро переключаться между двумя последними каталогами. Каждый раз, когда вы вводитеcd -
, вы возвращаетесь в предыдущий каталог, что обеспечивает простую, но ограниченную историю (глубина равна 1). -
pushd
иpopd
: Эти команды позволяют управлять стеком каталогов.pushd
добавляет текущий каталог в стек и переходит в указанный каталог, тогда какpopd
возвращает вас в предыдущий каталог из стека. Командаdirs
позволяет просмотреть содержимое стека текущих каталогов.
2. Создание пользовательского решения
Для более сложной истории каталога можно создать пользовательские функции. Например, можно переопределить команду cd
, чтобы она также сохраняла ваши перемещения в файл:
cdHistoryFile=~/.bash_cdhistory
cd() {
builtin cd "$@" && echo "$PWD" >> "$cdHistoryFile"
}
cdh() {
local IFS=$'\n'
local directories=()
for line in `tac "$cdHistoryFile"`; do directories+=("$line"); done
select dir in "${directories[@]}"; do
[ -n "$dir" ] && cd "$dir" && break
done
}
В этом примере, каждый раз, когда вы используете cd
, текущий каталог записывается в файл, и вы можете просмотреть его с помощью команды cdh
.
3. Сторонние инструменты
Если вам нужна более функциональная и удобная система управления историей каталогов, существуют несколько сторонних инструментов:
-
autojump: Этот инструмент позволяет вам быстро переходить в frequently в используемые каталоги, основываясь на вашей истории использования. Он строит базу данных о каталогах, что позволяет использовать команды
j <что-то>
, чтобы быстро перемещаться. -
fzf: Это инструмент для поиска и выбора, который может быть интегрирован с командой
cd
. После активации вы можете использоватьAlt + C
для открытия интерфейса поиска каталога. -
dirjump: Этот скрипт отслеживает 10 последних использованных директорий и позволяет вам просто ввести номер, чтобы перейти в нужный каталог.
-
WCD: Это команда, которая позволяет вам просто ввести часть имени каталога для быстрого перехода к нему, используя хранимая информация о предыдущих перемещениях.
Заключение
Хотя Bash не предоставляет встроенной полной истории каталогов, существует множество решений, которые могут помочь вам достичь аналогичной функциональности. Выбор между встроенными командами и сторонними инструментами зависит от ваших потребностей и стиля работы. Экспериментируйте с представленными вариантами, чтобы найти самый удобный для вас способ управления историей каталогов в Bash. Ваши чувства по поводу удобства использования и производительности могут варьироваться, поэтому рекомендуется попробовать несколько решений, чтобы определить, какое из них более эффективно решает вашу задачу.