ディレクトリツリー/ファイル名を扱うときの簡単なbashのヒント

ディレクトリツリー/ファイル名を扱うときの簡単なbashのヒント

Ubuntu 14.04以降では、bash私のPS1変数は次に終わります。

\u@\h:\w\$

プロンプトが次のように表示されるように

user@machinename:/home/mydirectory$

ただし、時には現在のディレクトリの名前が非常に長いか、名前が非常に長いディレクトリにあるため、プロンプトは次のようになります。

user@machinename:/home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name$

これにより、端末の行がいっぱいになり、カーソルが別の行に移動して迷惑になります。

次のようなものを手に入れたい

user@machinename:/home/mydirectory1/...another_long_name$

PS1ディレクトリ名が特定の文字数を超えずに短いプロンプトが表示されるように、ディレクトリ名を「ラップ」して「圧縮」する変数を定義する方法はありますか?

答え1

まず\w\Wこれにより、フルパスではなく現在のディレクトリの名前のみが印刷されます。

terdon@oregano:/home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name $ PS1="\u@\h:\W \$ "
terdon@oregano:my_actual_directory_with_another_long_name $ 

ディレクトリ名自体が長すぎると、この方法では十分ではありません。この場合、このPROMPT_COMMAND変数を使用できます。これは、各プロンプトが表示される前に値がコマンドとして実行される特殊なbash変数です。したがって、現在のディレクトリパスの長さに応じて、必要なヒントを設定する関数に設定すると、必要なものが得られます。たとえば、次の行を次の行に追加します~/.bashrc

get_PS1(){
        limit=${1:-20}
        if [[ "${#PWD}" -gt "$limit" ]]; then
                ## Take the first 5 characters of the path
                left="${PWD:0:5}"
                ## ${#PWD} is the length of $PWD. Get the last $limit
                ##  characters of $PWD.
                right="${PWD:$((${#PWD}-$limit)):${#PWD}}"
                PS1="\[\033[01;33m\]\u@\h\[\033[01;34m\] ${left}...${right} \$\[\033[00m\] "
        else
                PS1="\[\033[01;33m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] "
        fi


}
PROMPT_COMMAND=get_PS1

効果は次のとおりです。

terdon@oregano ~ $ cd /home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name
terdon@oregano /home...th_another_long_name $ 

答え2

これに対する私の主な解決策は、文字戻りを追加することでした。

したがって、私のプロンプト(より長くするための追加コンテンツを含む)は次のようになります。

ここに画像の説明を入力してください。

$が新しい行に返されるのを見ることができます。

私はこれを通してこれを達成しました。

HOST='\[\033[02;36m\]\h'; HOST=' '$HOST
TIME='\[\033[01;31m\]\t \[\033[01;32m\]'
LOCATION=' \[\033[01;34m\]`pwd | sed "s#\(/[^/]\{1,\}/[^/]\{1,\}/[^/]\{1,\}/\).*\(/[^/]\{1,\}/[^/]\{1,\}\)/\{0,1\}#\1_\2#g"`'
PS1=$TIME$USER$HOST$LOCATION'\n\$ '

別の行にあっても、次の非常に長いディレクトリツリーがあります。

/home/durrantm/Dropbox/96_2013_archive/work/code/ruby__rails短縮

/home/durrantm/Dropbox/_/code/ruby__rails

つまり、「最初の3つのディレクトリ/_/と下位2つのディレクトリ」は、一般的に私が興味を持っている部分です。

これにより、ディレクトリツリーの長さのために行が長すぎるのを防ぐことができます。常に完全なディレクトリツリーが必要な場合は、LOCATIONを調整してください。

LOCATION=' \[\033[01;34m\]`pwd`'

答え3

~/.bash_prompt 生成:

maxlen=36
# set leftlen to zero for printing just the right part of the path
leftlen=19
shortened="..."
# Default PWD
nPWD=${PWD}
if [ ${#nPWD} -gt $maxlen ]; then
  offset=$(( ${#nPWD} - $maxlen + $leftlen ))
  nPWD="${nPWD:0:$leftlen}${shortened}${nPWD:$offset:$maxlen}"
else
  nPWD='\w'
fi
echo "\u@\h:$nPWD\$ "

私の~/.bash_profileに追加されました:

function prompt_command {
  export PS1=$(~/.bash_prompt)
}
export PROMPT_COMMAND=prompt_command

出力は次のとおりです

user@machinename:/home/mydirectory1/...another_long_name$

答え4

私はこれを使用し、複数行に折り返し、長さだけインデントするので、user@host現在がPS1実際に " \u@\h:\w$"と仮定します。パスをカットせずに現在の端末幅に合わせます。パスだけが分割されるため、/非常に長いディレクトリは正常に処理されません(ただし、選択/コピーのためのスペースは保存されます)。これにより、常に少なくとも20文字を入力できます。

readonly _PS1="${PS1}" 2>/dev/null

function myprompt()
{
    local IFS
    local nn nb pbits xpwd="" ww=60 len=0 pp='\\w\$ '
    local indent uh="${LOGNAME}@${HOSTNAME//.*/}"

    test -n "$COLUMNS" && let ww=$COLUMNS-20  # may be unset at startup

    PS1="${_PS1}"
    if [ ${#PWD} -ge $ww ]; then
        printf -v indent "%${#uh}s%s" " " "> "  # indent strlen(user@host)

        IFS=/ pbits=( $PWD ); unset IFS
        nb=${#pbits[*]}
        for ((nn=1; nn<nb; nn++)) {
            if [ $(( $len + 1 + ${#pbits[$nn]} )) -gt $ww ]; then
                xpwd="${xpwd}/...\n${indent}..."
                len=0
            fi
            xpwd="${xpwd}/${pbits[$nn]}"
            let len=len+1+${#pbits[$nn]}
        }
        # add another newline+indent if the input space is too tight
        if (( ( ${#uh} + len ) > ww )); then
            printf -v xpwd "${xpwd}\n%${#uh}s" " " 
        fi 
        PS1="${PS1/$pp/$xpwd}$ "    
    fi
}
PROMPT_COMMAND=myprompt

これは魔法を取り除き\w(これだけ一致\w$PS1、それを通常の文字列に置き換えることによって$PWD行われます。PS1に保存されている元の値から毎回再計算されます。_PS1つまり、「見えない」エスケープも保存されるという意味です。完全な元のプロンプト文字列xtermと太字のプロンプトは次のとおりです。

PS1="\[\033]0;\u@\h:\w\007\]\[$(tput bold)\]\u@\h\[$(tput sgr0)\]:\w$ "

最終結果は80列ターミナルです。

mr@onomatopoeia:~$ cd /usr/src/linux/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace
mr@onomatopoeia:/usr/src/linux/tools/perf/scripts/perl/Perf-Trace-Util/lib/...
               > .../Perf/Trace$ _

これはbash-3.2から利用可能ですprintf -v var。なぜならさまざまな複雑さ他のバリエーションにいくつかの調整が必要ですPS1

(パスは次のとおりです。xtermタイトルバーはラップされたり省略されたりしません。これは、ここにある他の答えの1つを上記の関数に組み込むことによって行うことができます。 )

関連情報