bash で tcsh dextract のような pushd 機能を取得する

bash で tcsh dextract のような pushd 機能を取得する

私は (4.1.2(1)-release) が大好きですが、オプションを有効にしてを実装するbash方法の方が断然好みなので、そのためデフォルトのシェルとして使用することを拒否しています。 のようなディレクトリ スタック コマンド セットを に実装した人はいますか。それとも、を有効にしてのように動作させる方法をまだ見つけていないのでしょうか。tcshpushd +Ndextractbashdextractbashbashtcshdextract

bash問題点:の後にディレクトリ スタックを離れる順序pushd +N。例:

$ cd /tmp
$ pushd a
/tmp/a /tmp
$ pushd ../b
/tmp/b /tmp/a /tmp
$ pushd ../c
/tmp/c /tmp/b /tmp/a /tmp
$ pushd +1
/tmp/b /tmp/a /tmp /tmp/c

bashを実行すると、 (およびデフォルトのtcsh) が他のすべてのディレクトリの位置を回転するのはなぜですかpushd +1? これはなぜ便利なのですか? (おそらく誰かが説明してくれたら、この動作を理解して慣れるかもしれません。) と を比較するとtcshdextractはそれを抽出して一番上に置くだけです。

% set dextract
% cd /tmp
% pushd a
/tmp/a /tmp 
% pushd ../b
/tmp/b /tmp/a /tmp 
% pushd ../c
/tmp/c /tmp/b /tmp/a /tmp 
% pushd +1
/tmp/b /tmp/c /tmp/a /tmp 

dirsディレクトリの残りの順序は変更されないことに注意してください。順序がローテーションされないと、頭の中で追跡しやすくなるため、常に を実行して目的のディレクトリを検索する必要がなくなるため、これは重要だと考えています。

これに取り掛かるとしたら、どこから始めればよいでしょうか。変数 があることはわかりますDIRSTACKが、これは正しくありません (スタックに 4 つのエントリがある場合は空です)。ただし、これを変更するとスタックが変更されます (ただし、正しくはありません)。

答え1

少しの努力とインスピレーションを経て、私は問題を解決しました。

# dextract-like pushd -- push $1'st directory to top of stack and shift rest down
function pushd {
    local t
    if [[ $1 =~ ^[-+]?[0-9]+$ ]]; then
        pos=$1
        [[ ${pos} -lt 0 ]] && ((pos=${#DIRSTACK[@]}+${pos}))
        if [[ ${pos} -gt 0 && ${pos} -lt ${#DIRSTACK[@]} ]]; then
            t="${DIRSTACK[$pos]}"
            # This is crufty. You can't put ~ in DIRSTACK, except the
            # shell will put it into position zero when it refers to your
            # own directory (not anyone else's!). So replace any occurrences.
            DIRSTACK=("" "${DIRSTACK[0]/#~/${HOME}}" "${DIRSTACK[@]:1:${pos}-1}" "${DIRSTACK[@]:${pos}+1}")
            cd "$t"
            builtin dirs -v
        else
            echo "$0: pushd: $1: directory stack index out of range" 1>&2
        fi
    else
        builtin pushd "$@" >/dev/null || return
        cd .
        builtin dirs -v
    fi
}

関連情報