シェルで深い階層まで潜っているとき、何階層か上にcdしようとすると cd ../../../ とか書くハメになり面倒くさい。
pecoでちょっと簡単にできるようにした。

やりたいこと

カーソル移動だけで上の階層に移動できるようにする。

cdup_example.gif

方法

~/.bashrc に以下のように書いておく。

function cdup(){
  cd `for i in $(seq 0 $(pwd | awk -F/ '{print NF}')); do pwd | grep -oE "^/([^/]*/){$i}" ; done | peco`
}

説明とか

  • $(pwd | awk -F/ '{print NF}')
    pwd/foo/bar/baz のような文字列が返る。
    awk -F/ '{print NF}' ではスラッシュ区切りとしてその文字列にいくつフィールドがあるかが返る。
    /foo/bar/baz の場合は4が返る。

  • pwd | grep -oE "^/([^/]*/){$i}"
    grep のoオプションはヒットした文字列だけを取り出す。Eオプションは拡張正規表現を使えるようにする。
    pwd の文字列で、最初のスラッシュを0番目として、 $i 番目のスラッシュまでを取り出すみたいな感じ。

  • forループの中で $i には無駄に大きい値が入るが、どうせマッチしないだけなので無視

  • 全体をバックスラッシュで囲んでcdしてるのが気になる件
    本当は

    for i in $(seq 0 $(pwd | awk -F/ '{print NF}')); do pwd | grep -oE "^/([^/]*/){$i}" ; done | peco | xargs cd
    

    のようにパイプでつなぎたかった。でもできない。どうやらcdはシェルのビルトインコマンドなのでできないようだ。

  • (おまけ) mkdirしたあとに cd <ESC> . でそのディレクトリにcdするコマンドになる
    知らなかった…。ただシェルによるよう。

参考