web-dev-qa-db-ja.com

CDの履歴はありますか?

cd -は最後にアクセスしたディレクトリに移動できます。前回以外の歴史を訪ねることはできますか?

45
Tim

探しているコマンドはpushdpopdです。

here から、pushdおよびpopdの実用的な例を見ることができます。

mkdir /tmp/dir1
mkdir /tmp/dir2
mkdir /tmp/dir3
mkdir /tmp/dir4

cd /tmp/dir1
pushd .

cd /tmp/dir2
pushd .

cd /tmp/dir3
pushd .

cd /tmp/dir4
pushd .

dirs
/tmp/dir4 /tmp/dir4 /tmp/dir3 /tmp/dir2 /tmp/dir1
32
Ramesh

使用しているシェルを指定していないため、これをzshをアドバタイズする言い訳にしましょう。

はい、cdの履歴があります。つまり、cd -2cd -4など。非常に便利ですcd -TAB、特に完成システムと色が有効になっている場合:

これは私が.zshrcに持っているものです:

setopt AUTO_PUSHD                  # pushes the old directory onto the stack
setopt PUSHD_MINUS                 # exchange the meanings of '+' and '-'
setopt CDABLE_VARS                 # expand the expression (allows 'cd -2/tmp')
autoload -U compinit && compinit   # load + start completion
zstyle ':completion:*:directory-stack' list-colors '=(#b) #([0-9]#)*( *)==95=38;5;12'

そしてその結果:

enter image description here

57
jimmij

「より多くの歴史」に関するあなたの質問に答えること。いいえcd - Bashの機能は、「フリップ」できる単一のディレクトリのみをサポートします。 @Rameshが彼の答えで述べているように。より長いディレクトリの履歴が必要な場合は、pushdおよびpopdを使用してディレクトリを保存するか、以前のディレクトリに戻ることができます。

dirsコマンドを使用して、現在スタックにあるもののリストを表示することもできます。

pushdコマンドとpopdコマンドの使用方法は? というタイトルのこの回答から詳細な説明を見つけることができます。

13
slm

Bash用のmy dirhistory ユーティリティをインストールして使用できます。

基本的に、それはすべてのシェルからディレクトリの変更を収集するデーモンであり、履歴を表示して切り替え先のディレクトリを選択できるCdkプログラムです(スタックに限定されません)。

8
cjm

必要な数の履歴があります。

cd() {
[ "$((${DIRSTACKMAX##*[!0-9]*}0/10))" -gt 0 ] &&
        set -- "$@" "$DIRSTACK"               &&
        DIRSTACK='pwd -P >&3; command cd'     ||
        { command cd "$@"; return; }
_q()    while   case "$1" in (*\'*) :   ;;      (*)
                ! DIRSTACK="$DIRSTACK '$2$1'"   ;;esac
        do      set -- "${1#*\'}" "$2${1%%\'*}'\''"
        done
while   [ "$#" -gt 1 ]
do      case    ${1:---} in (-|[!-]*|-*[!0-9]*) : ;;
        (*)     eval "  set $((${1#-}+1))"' "${'"$#}\""
                eval '  set -- "$2"'" $2"'
                        set -- "${'"$1"'}" "$1"'
        ;;esac; _q "$1"; shift
done
eval "  DIRSTACK=; $DIRSTACK    &&"'
        _q "$OLDPWD"            &&
        DIRSTACK=$DIRSTACK\ $1
        set "$?" "${DIRSTACK:=$1}"'" $1
"       3>/dev/null
[ "$(($#-1))" -gt "$DIRSTACKMAX" ] &&
        DIRSTACK="${DIRSTACK% \'/*}"
unset -f _q; return "$1"
}

これは、POSIX互換シェルがzsh- style cd履歴を提供できるようにするシェル関数です。単一のサブシェルを呼び出さずにすべての処理を実行します。フローは非常に適切であると思います。適度なテストですべてのケースを正しく処理しているようです。

関数は、完全に移植可能な構文に依拠しながら、環境と同じようにうまく再生しようとします。これは、1つの仮定にすぎず、$DIRSTACK環境変数は、そのプロパティと同じように処理することです。

$DIRSTACKに格納されているすべてのパスを正規化し、すべてを単一引用符でシリアル化します。ただし、変数の値に追加する前に、それぞれが安全に引用されてシリアル化されるため、問題が発生することはありません。あらゆる種類の特殊文字。 $DIRSTACKMAX環境変数が設定されている場合、履歴に保持するパスの数の上限として使用されます。それ以外の場合、制限は1です。

関数を読み込む場合は、通常どおりcdを実行しますが、変更ディレクトリの履歴をさかのぼってcd -[num]を実行することもできます。

関数の主なメカニズムは、cd自体と、${OLD,}PWD環境変数です。 POSIXは、cdがパスの移動ごとにこれらを変更することを指定しています。これにより、シェルの組み込み変数を使用し、必要なだけ値を保存します。

7
mikeserv

acd_func.sh スクリプトは、ユーザーが記述したとおりに実行します。基本的にcd関数をオーバーロードし、cd --と入力して、以前にアクセスしたディレクトリのリストを取得し、そこから番号で選択できます。これなしでbashを使用するのは非常に難しく、新しいシステムに最初にインストールするのはこれが最初です。

4
Nick Edwards

他のものはすでにいくつかの興味深い解決策をカバーしました。しばらく前に、「まっすぐな履歴」を実行するようにすばやく変更できる関連問題の独自のソリューションを作成しました。私は基本的に、いくつかの一般的に使用されるディレクトリに「ラベルを付ける」ことを望んでおり、allシェルを開いてそれらを表示し、再起動の間も持続することを望んでいました。

#dir_labels
#functions to load and retrieve list of dir aliases

function goto_complete {
    unset dir_labels
    declare -A dir_labels
    {
    while read line; do
        ll_pre="${line%% *}"
        ll_dir="${line#* }"
        dir_labels["$ll_pre"]="$ll_dir"
    done
    } < ~/.dir_labels
    unset ll_pre
    unset ll_dir

    local cur possib
    cur="${COMP_WORDS[COMP_CWORD]}"
    possib="${!dir_labels[@]}"
    COMPREPLY=( $(compgen -W "${possib}" -- ${cur}) )
}

complete -F goto_complete goto

function goto {
    unset dir_labels
    declare -A dir_labels
    {
    while read line; do
        ll_pre="${line%% *}"
        ll_dir="${line#* }"
        dir_labels["$ll_pre"]="$ll_dir"
    done
    } < ~/.dir_labels
    unset ll_pre
    unset ll_dir

    if [ $# -gt 0 ]; then
    key="$1"
    else
    key=default
    fi
    target="${dir_labels[$key]}"
    if [ -d "$target" ]; then
    cd "$target"
    echo "goto $key: '$target'"
    else
    echo "directory '$target' does not exist"
    fi
}

function label {
    unset dir_labels
    declare -A dir_labels
    {
    while read line; do
        ll_pre="${line%% *}"
        ll_dir="${line#* }"
        dir_labels["$ll_pre"]="$ll_dir"
    done
    } < ~/.dir_labels
    unset ll_pre
    unset ll_dir

    if [ $# -gt 0 ]; then
    target="$1"
    else
    target="default"
    fi
    dir_labels["$target"]=$PWD
    for i in "${!dir_labels[@]}"; do
    echo "$i ${dir_labels[$i]}"
    done > ~/.dir_labels
}

基本的に私はlabel fooを実行して現在のディレクトリfooを呼び出し、次にどのシェルからでもgoto foocdを直接呼び出します。空の引数:labelは、gotoのデフォルトターゲットを作成します。

エイリアスの自動削除を実装する手間はしませんでしたが、それ以外の場合は、これをわずかに変更した形で使用しています。

3
orion

http://fex.belwue.de/fstools/bash.html の「cd history」関数を使用できます

これまでに行ったすべてのディレクトリが記憶され、「cdh」を使用すると、最後の9つのディレクトリのリストが表示されます。番号を入力するだけで、このディレクトリに戻ります。

例:

 framstag @ wupp:/: cDH
 1:/usr/local/bin
2:/var
3:/
4:/tmp/135_pana/1280
5: /tmp/135_pana
6:/tmp/weihnachtsfeier
7:/tmp
8:/local/home/framstag
選択: 4
 framstag @ wupp:/ tmp/135_pana/1280:

cdhはautocd別名「cd without cd」で機能します。cdやpushdを入力する必要はありません。

2
Framstag

私の拡張された「cd」機能をお勧めします。

https://github.com/dczhu/ltcd

enter image description here

生活を楽にする次の機能を提供します。

  • すべての端末タブ/ウィンドウから最近アクセスしたディレクトリを表示するグローバルディレクトリリスト。
  • 現在のシェルセッションに対してローカルなローカルディレクトリリスト。
  • どちらのリストでも、j/k(下へ/上へ)、数字、およびWord検索を使用したクイックナビゲーションがサポートされています。
  • グローバルフリージャンプ(たとえば、「cd dir」または「cd ar」で/ path/to/foo/bar/directory /に移動)。
2
treulz

312ページの「シェルプログラミング、4e」のcdh関数を参照してください。履歴は配列に保持されます。

これはより高度なバージョンです: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M

履歴をファイルCDHISTFILEに保存し、文字列を含む最新のディレクトリに変更できるようにします。

cd -src

alias cd=_cdを実行することにより、既存のcdコマンドの上にインストールされます。

1
user2251295

fzf-marks を可能な解決策として追加したかっただけです。

インストールすると、コマンドmarkおよびjumpが追加および検索されますブックマークされたディレクトリの場合(はい、それは完全な履歴ではなく、自分でブックマークしたものだけです)。

Pushd/popd itセッション固有の動作に関する問題、つまり、異なるbashセッションなどで同じスタックを使用したいので、fzf-marksが発生する可能性があります。

1

bashの場合:基本的に:cdを使用する代わりにpushdを使用してディレクトリを変更すると、ディレクトリが保存されます(つまり、スタックされる)。

pushd /home; pushd /var; pushd log

スタックを表示するにはdirsを使用し、ナビゲーションを簡単にするには(「スタックエントリ」の数を取得するには:

dirs -v

出力:

me@myhost:/home$ dirs -v
 0  /home
 1  /var
 2  /tmp

これらの数値をcdおよび~で使用します。

cd ~1

しかし、これらの数値は再配置され、位置「0」が変更されるため、次のように、ディレクトリをpushdで2度最上位に(または、位置0でダミーを使用して)ください。

me@myhost:/home$ dirs -v
 0  /home
 1  /home
 2  /var
 3  /tmp

現在、1..3はその位置を維持しますこれをどこかで読みましたが、もうわかりません。クレジットを提供しないことを申し訳ありません

(スタックから現在のディレクトリを解放/履歴から削除するには、popdを使用します)

1
eli

@mikeservの回答を試しましたが、うまくいきませんでした。私はそれを修正する方法を理解できなかったので、私は自分で書きました:

cd() {
    # Set the current directory to the 0th history item
    cd_history[0]=$PWD
    if [[ $1 == -h ]]; then
        for i in ${!cd_history[@]}; do
            echo $i: "${cd_history[$i]}"
        done
        return
    Elif [[ $1 =~ ^-[0-9]+ ]]; then
        builtin cd "${cd_history[${1//-}]}" || # Remove the argument's dash
        return 
    else
        builtin cd "$@" || return # Bail if cd fails
    fi
    # cd_history = ["", $OLDPWD, cd_history[1:]]
    cd_history=("" "$OLDPWD" "${cd_history[@]:1:${#cd_history[@]}}")
}

これは GitHub Gist としても利用できます。これを使用するには、関数を.bashrcまたは類似のものに貼り付けるだけで、cd -5などの操作を行って5に戻ることができます番目cd -hを使用すると、履歴の概要が表示されます。

1
saagarjha