web-dev-qa-db-ja.com

コマンドラインプロンプトの現在のディレクトリを短縮するにはどうすればよいですか?

私はUbuntuを使用していますが、深いディレクトリ階層で作業しているときにbashのこの長いプロンプトにうんざりしています。そこで、PS1を微調整して、作業ディレクトリの部分を次のように短縮したいと思います。

現在私が持っているもの:

pajton@dragon:~/workspace/projects/project1/folder1/test$

そして持ちたい:

pajton@dragon:~/workspace/.../folder1/test$

Len($ PWD)が所定のしきい値を超えると、切り捨てが発生します。常に最初のパスコンポーネントと少なくとも1つの最後のパスコンポーネントを保持したいです。次に、スペースが許す限り、右側から取得するコンポーネントを追加します。

これは私が現在持っているものです。動作しますが、1)最初のパスコンポーネントを保持しない、2)境界でのパスの切断を尊重しない:

pwd_length=14
pwd_symbol="..."
newPWD="${PWD/#$HOME/~}"

if [ $(echo -n $newPWD | wc -c | tr -d " ") -gt $pwd_length ]
then
   newPWD="...$(echo -n $PWD | sed -e "s/.*\(.\{$pwd_length\}\)/\1/")"
else
   newPWD="$(echo -n $PWD)"
fi

そして結果:

pajton@dragon:...sth/folder1/sample$ 

前もって感謝します!

52
pajton

あなたのケースでは、sedの代わりにawkを使用するこのスクリプトを検討してください。

_pwd_length=14
pwd_symbol="..."
newPWD="${PWD/#$HOME/~}"
if [ $(echo -n $newPWD | wc -c | tr -d " ") -gt $pwd_length ]
then
   newPWD=$(echo -n $newPWD | awk -F '/' '{
   print $1 "/" $2 "/.../" $(NF-1) "/" $(NF)}')
fi
PS1='${newPWD}$ '
_

ディレクトリ_~/workspace/projects/project1/folder1/test_の例では、PS1は次のようになります:_~/workspace/.../folder1/test_

更新

上記のソリューションではプロンプトが設定されますが、コメントで指摘したように、ディレクトリを変更してもPS1が動的に変更されることはありません。そこで、ディレクトリを変更したときにPS1を動的に設定するソリューションを次に示します。

.bashrcファイルに次の2行を追加します。

_export MYPS='$(echo -n "${PWD/#$HOME/~}" | awk -F "/" '"'"'{
if (length($0) > 14) { if (NF>4) print $1 "/" $2 "/.../" $(NF-1) "/" $NF;
else if (NF>3) print $1 "/" $2 "/.../" $NF;
else print $1 "/.../" $NF; }
else print $0;}'"'"')'
PS1='$(eval "echo ${MYPS}")$ '
_

awkのif (NF > 4 && length($0) > 14)条件は、現在のディレクトリの深さが3ディレクトリを超える場合、および_$PWD_の長さが14文字を超える場合にのみ特別な処理を適用し、そうでない場合はPS1を_$PWD_。

例:現在のディレクトリが_~/workspace/projects/project1$_の場合、PS1は_~/workspace/projects/project1$_になります

.bashrcでの上記の効果は、PS1で次のようになります。

_~$ cd ~/workspace/projects/project1/folder1/test
~/workspace/.../folder1/test$ cd ..
~/workspace/.../project1/folder1$ cd ..
~/workspace/.../project1$ cd ..
~/.../projects$ cd ..
~/workspace$ cd ..
~$
_

ディレクトリを変更すると、プロンプトがどのように変化するかに注目してください。これがあなたが望んでいたものではない場合、私に知らせてください。

46
anubhava

はるかに単純なソリューションを探していて、パスの最初のディレクトリの名前を必要としない人のために、BashにはPrompt_DIRTRIM変数を使用したこのサポートが組み込まれています。 ドキュメントから

Prompt_DIRTRIM

ゼロより大きい数値に設定すると、この値は、\ wおよび\ Wプロンプト文字列エスケープを展開するときに保持する後続ディレクトリコンポーネントの数として使用されます(プロンプトの印刷を参照)。削除された文字は省略記号に置き換えられます。

例えば:

~$ mkdir -p a/b/c/d/e/f
~$ cd a/b/c/d/e/f
~/a/b/c/d/e/f$ export Prompt_DIRTRIM=2
~/.../e/f$ Prompt_DIRTRIM=3
~/.../d/e/f$ 

欠点:パスの長さではなく、ディレクトリレベルに依存します。

利点:非常に簡単です。 export Prompt_DIRTRIM=2.bashrcに追加するだけです。

113
imgx64

これは、anubhavaのソリューションに基づいて使用するものです。プロンプトとウィンドウのタイトルの両方を設定します。 awkスクリプトは読みやすいので、簡単に微調整/カスタマイズできます。

16文字を超え、4レベルの深さがある場合、パスを折りたたみます。さらに、...には折りたたまれたディレクトリの数も示されるので、パスの深さを把握できます。つまり、~/usr/..4../path2/path1は、4つのレベルが折り畳まれたことを示します。

# define the awk script using heredoc notation for easy modification
MYPSDIR_AWK=$(cat << 'EOF'
BEGIN { FS = OFS = "/" }
{ 
   sub(ENVIRON["HOME"], "~");
   if (length($0) > 16 && NF > 4)
      print $1,$2,".." NF-4 "..",$(NF-1),$NF
   else
      print $0
}
EOF
)

# my replacement for \w Prompt expansion
export MYPSDIR='$(echo -n "$PWD" | awk "$MYPSDIR_AWK")'

# the fancy colorized Prompt: [0 user@Host ~]$
# return code is in green, user@Host is in bold/white
export PS1='[\[\033[1;32m\]$?\[\033[0;0m\] \[\033[0;1m\]\u@\h\[\033[0;0m\] $(eval "echo ${MYPSDIR}")]$ '

# set x/ssh window title as well
export Prompt_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*} $(eval "echo ${MYPSDIR}")\007"'

実際の動作は次のとおりです。緑の0は最後のコマンドのリターンコードです。

enter image description here

9
raychi
echo -n $PWD | sed -re "s|(~?/[^/]*/).*(.{$pwd_length})|\1...\2|"

利便性のためだけに-rを使用し、括弧の前のバックスラッシュを省略できます。便宜上、区切り文字としても-コマンド内でスラッシュを使用するためです。あなたのホームは〜としても表示されるので、〜/ foo/bar/baz /は〜/ foo /.../ bazで終わり、/ foo/bar/baz /は/foo/.../bazとして終わるはずです/。

そのため、オプションの〜を使用し、その後にスラッシュ、名前、スラッシュを\ 1、次に何か、次に残りを\ 2とします。

5
user unknown

sedawkを使用してプロンプトを生成する別のアプローチ。これにより、$HOMEディレクトリが〜に変換され、ルートディレクトリ、最下位レベル(現在のディレクトリ)、およびその親が表示され、その間のディレクトリごとに..で区切られます。

.bashrc(またはOS Xでは.bash_profile)の内部:

function generate_pwd {
  pwd | sed s.$HOME.~.g | awk -F"/" '
  BEGIN { ORS="/" }
  END {
  for (i=1; i<= NF; i++) {
      if ((i == 1 && $1 != "") || i == NF-1 || i == NF) {
        print $i
      }
      else if (i == 1 && $1 == "") {
        print "/"$2
        i++
      }
      else {
        print ".."
      }
    }
  }'
}
export PS1="\$(generate_pwd) -> "

このスクリプトは、awkの組み込みNF変数(フィールド数)および位置変数($1, $2 ...)を使用して、ORS変数(出力レコード区切り文字)で区切られた各フィールド(ディレクトリ名)を印刷します)。プロンプトで内部ディレクトリを..に折りたたみます。

使用例:

~/ -> cd Documents/
~/Documents/ -> cd scripts/
~/Documents/scripts/ -> cd test1/
~/../scripts/test1/ -> cd test2
~/../../test1/test2/ -> pwd
/Users/Brandon/Documents/scripts/test1/test2
~/../../test1/test2/ -> cd test3/
~/../../../test2/test3/ -> cd test4/
~/../../../../test3/test4/ -> pwd
/Users/Brandon/Documents/scripts/test1/test2/test3/test4
~/../../../../test3/test4/ -> cd /usr/
/usr/ -> cd local/
/usr/local/ -> cd etc/
/usr/local/etc/ -> cd openssl/
/usr/../etc/openssl/ -> cd private/
/usr/../../openssl/private/ ->
3
Brandon

_Prompt_DIRTRIM_を使用するbash組み込みソリューションとは別に、$(pwd | tail -c16)を試してください。これは、他のほとんどの回答よりも少しシンプルですが、現在のディレクトリの最後の16文字を提供します。もちろん、16を任意の数字に置き換えます。

1
Sebastian Mach

以前のソリューションとそれほど変わりません。ただし、もう少し読みやすく編集可能かもしれません。ただし、フォルダー名の境界に対する解決策はなく、プロンプトの長さにのみ焦点を当てています。

### SET MY Prompt ###
if [ -n "$PS1" ]; then
    # A temporary variable to contain our Prompt command
    NEW_Prompt_COMMAND='
        pwd_short=${PWD/#$HOME/\~};
        if [ ${#pwd_short} -gt 53 ]; then
            TRIMMED_PWD=${pwd_short: 0: 25}...${pwd_short: -25}
        else
            TRIMMED_PWD=${pwd_short}
        fi
    '

    # If there's an existing Prompt command, let's not 
    # clobber it
    if [ -n "$Prompt_COMMAND" ]; then
        Prompt_COMMAND="$Prompt_COMMAND;$NEW_Prompt_COMMAND"
    else
        Prompt_COMMAND="$NEW_Prompt_COMMAND"
    fi

    # We're done with our temporary variable
    unset NEW_Prompt_COMMAND

    # Set PS1 with our new variable
    # \h - hostname, \u - username
    PS1='\u@\h: $TRIMMED_PWD\$ '
fi

.bashrcファイルに追加されました。プロンプトのすべての部分が適切に更新されます。ホームディレクトリにいる場合、最初の部分は短縮されます。 例:

user @ computer:〜/ misc/projs/solardrivers ... src/com/mycompany/handles $

0
karnbo

なぜ${string:position:length}を使用しないのですか? ${string:-$max_chars}を実行して、文字列の最後の${max_chars}を取得できます。

負の値に注意

0
Naus Caligo

https://github.com/chrissound/SodiumSierraStrawberry

次のようなパスを切り捨てることができます。

から:/ home/sodium/Projects/Personal/Sierra/Super/Long/Path/HolyAvacado

宛先:"プロジェクト/ Sie…/ Sup…/ Lon…/ Pat…/ HolyAvacado /

0
generatePwd(){
  set -- "`pwd | sed -e s.${HOME}.~.g`"
  IFS="/"; declare -a array=($*)
  srt=""
  count=0
  for i in ${!array[@]}; do
      # echo ${array[i]} - $i/${#array[@]}
      if [[ $i == 0 ]]; then
        srt+=""
      Elif [[ $i == $((${#array[@]}-1)) ]] || [[ $i == $((${#array[@]}-2)) ]]; then
          srt+="/${array[i]}"
      else
        count=$((${count}+1))
      fi
  done
  if [[ $count != 0 ]]; then
    srt="${array[0]}/.$count.$srt"
  else
    srt="${array[0]}$srt"
  fi
  echo "${srt}"
}

pS1をエクスポート

PS1="\$(generatePwd)"

コンソール

$ ~/.3./machine-learning/deep-learning-computer-vision