Существует ли история каталогов для bash?

Вопрос или проблема

Существует ли что-то похожее на обратный поиск истории команд bash (CtrlR), но только для директорий?

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

По сути, это давало бы аналогичные результаты, как использование !?, но только соответствующие командам с 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 для быстрого навигации по истории директорий:

https://github.com/dczhu/ltcd

cd demo gif

Он предоставляет следующие функции для упрощения жизни:

  • Глобальный список директорий, который показывает недавно посещенные директории из всех вкладок/окон терминала.
  • Локальный список директорий, который локален для текущей сессии оболочки.
  • Оба списка поддерживают быструю навигацию с помощью 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] $ 

Я предложу еще одно решение: нечеткий поиск по пути

  • fzf

    После того, как вы запустите его в фоновом режиме, вы можете нажать Alt+C, чтобы открыть окно, где вы можете ввести нечеткую строку для поиска директорий. После того как вы выберете одну и нажмете Enter, fzf переключится на эту директорию.

    fzf

  • нечеткое завершение bash

  • Command-T:

    Command-T в действии

Смотрите также

Существуют также различные оболочки и расширения оболочек, которые поддерживают частичное автозаполнение путей, и 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…)

cdhist в действии

Итак, вы можете добавить этот фрагмент кода в ваш ~/.bashrc, который

  1. предоставляет пользовательскую команду 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"
        }
    
  2. и предоставляет команду поиска истории 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.

https://github.com/gawells/ariadne

Ответ или решение

История каталогов в 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. Ваши чувства по поводу удобства использования и производительности могут варьироваться, поэтому рекомендуется попробовать несколько решений, чтобы определить, какое из них более эффективно решает вашу задачу.

Оцените материал
Добавить комментарий

Капча загружается...