2016-05-27 13 views
5

私はちょうどtcshからbashに移動しました。特に、%c02ellipsisも設定されています)を使用してディレクトリ短縮プロンプトオプションを見落としました。Bashプロンプト短縮

PROMPT_DIRTRIMはほぼ正しいことをしています(省略記号は除きます)が、私はbash 3(OS X)にしかありません。私はthis recipe elsewhere on SOを見つけました。これは全長が短くなるため、ディレクトリの途中でパス名が壊れてしまいました。私は好きではありませんでした。

だから私はこの思い付いた:

PROMPT_DIRTRIM=2 ## from bash4, but used here 
dirtrim() 
{ 
    local NAME="$1" start= endelts= 
    [[ "$NAME" =~ ^"$HOME"(/|$) ]] && NAME="~${NAME#$HOME}" ## $HOME ==> ~ 
    IFS=/ read -ra elts <<< "$NAME";   ## split $PWD on "/" 
    start=$((${#elts[@]}-${PROMPT_DIRTRIM})) ## first element to retain 
    if [ ${start} -gt 1 ]; then  
     for ((i=${start}; i<${#elts[@]}; i++)); do 
      endelts="${endelts}/${elts[$i]}"; ## concat together the trailing path 
     done 
     NAME="...${endelts}" 
    fi 
    echo "$NAME"  
} 
PS1='\h:$(dirtrim "$PWD")\$ ' 

それは動作します:

blackat:~$ cd ~/Library/Application\ Support/Apple 
blackat:.../Application Support/Apple$ 
しかし、私は bashに新しめと明示的 for (())ループに不満です。しかし、私は、 elts分割の最後のエントリにdir名のスペースを正しく扱う方法で再結合する方法を見つけることができませんでした(例えば、 ${elts[@]:${start}}を使用)。それを行うためのヒントやその他の改善点はありますか?

(ちなみに、私は....このbashは、プログラミング言語であるという程度にプログラミングの質問、だと思う)

+1

Bashはプログラミング言語です。 –

+0

@Jonathan Leffler:合意しました - それは、2票の投票に応えて終了しました! –

+2

そして、私はBashプログラミングに関する質問がプログラミングの質問であることを肯定しているので、Stack Overflowでトピックに載っています。シェルプログラミングに関する話題をオフトピックとしてクローズすることは、以前は大きな問題でした。最近、私はそれが起こっているとは思わないが、それは単に私がそれを逃していることを意味するかもしれません、そして、それはいつも起こります。FWIW:私は長いプロンプトが好きではありません:私はプロンプトにパスを含めません。マシンの 'sphinx'では、私のプロンプトは 'Sphinx JL:'です。 Mac端末では、ターミナルのタイトルバーにパスを置くことができます(プロパティ - >ウィンドウとタイトルセクションを参照)。 –

答えて

3

あなたはこの試みることができる:

if ((start > 1)); then 
    name=$(IFS=/; echo .../"${elts[*]:start}") 
    # If your terminal is correctly set up for unicode, you can save two character positions: 
    # name=$(IFS=/; echo …/"${elts[*]:start}") 
fi 

注意をそれはbashの中で、((...))の内部と配列添字を含む算術コンテキストでは、変数の名前だけを書くことができます。 sigilsの必要はありません。

dirtrim() { 
    local path="$1"; 
    [[ $path =~ ^"$HOME"(/.*)? ]] && path=~${BASH_REMATCH[1]}; 
    ((PROMPT_DIRTRIM)) && 
    [[ $path =~ ...*((/[^/]*){$PROMPT_DIRTRIM}) ]] && 
    path=…${BASH_REMATCH[1]}; 
    echo "$path" 
} 

((PROMPT_DIRTRIM))テストが完全ではありません。それを行うには

もう一つの方法は、BASH_REMATCH配列ではなく、分割での正規表現のキャプチャを使用して、文字列を再結合、さらに別の解決策

if ((start > 1)); then 
    printf -v name "/%s" "${elts[@]:start}" 
    name=...$name 
fi 

だろう算術コンテキストでのbash評価の特殊性のために堅牢です。ディストリビューションのためにあなたが本当に[[ $PROMPT_DIRTRIM =~ ^[1-9][0-9]*$ ]]

+0

1.ケーシングについて合意した。私は[別の回答](http://stackoverflow.com/a/1618602/12266)から 'NAMES'を得ました。 2.私は '((start> 1))'を意味しました - もし 'start == 1'なら最初のエントリだけを残してください。私はあなたが 'name = $(IFS = /; echo ... /" $ {elts [*]:start} ")'を意味していたと思います( 'IFS = /'と '$'がありません) –

+0

@andrew:bash配列の最初のエントリにはインデックス0があります。タイプミスは正しいですが、私が入力したときにドアを急いでいました。申し訳ありません、私は今それを修正しました。 – rici

+0

はい、ゼロエントリは「〜」またはヌルなので、実際には「開始> 1」のときに短縮したいのです。 –

1

ない答えのようなものを好むかもしれませんが、あなたはどのようにmkshを見てすることがありますが、この実現:残念ながら

PS1=${| local e=$? ((e)) && REPLY+="$e|" REPLY+=${USER:=$(ulimit -c 0; id -un 2>/dev/null || echo \?)} [email protected]${HOSTNAME%%.*}: local d=${PWD:-?} p=~; [[ $p = ?(*/) ]] || d=${d/#$p/~} local m=${%d} n p=...; ((m > 0)) || m=${#d} ((m > (n = (COLUMNS/3 < 7 ? 7 : COLUMNS/3)))) && d=${d:(-n)} || p= REPLY+=$p$d return $e } 

、それは私が、bashにはないいくつかの拡張機能を使用しています信じる。

阿蘇、シェルを切り替えるので... fishとお考えですか?

これはすぐに使用できます。