21

PS1 環境変数に含まれる bash のプロンプト パス短縮機能を実装しました。これにより、作業ディレクトリがよりコンパクトでわかりやすいものに短縮されます。他にどのようなアイデアが存在するのか興味があります。

課題は次のとおりです。

次のように PS1 に含めることができるbash 関数_dir_chompを作成します (読みやすくするために改行が挿入されています)。

PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] $(
  _dir_chomp "$(pwd)" 20
)\[\033[01;37m\]$(parse_git_branch)\[\033[01;34m\] \$\[\033[00m\] '

「20」はソフトリミットとしての最大長のパラメータです。これらは例です:

  1. /usr/portage/media-plugins/banshee-community-extensions/filesになる/u/p/m/b/files
  2. /home/user1/media/video/music/live-setsになります~/m/v/m/live-sets($HOME の代わりに ~ 文字に注意してください)
  3. /home/user2/media変更されません (20 文字の制限を超えていません)
  4. /home/user1/this-is-a-very-long-path-name-with-more-than-20-charsになります~/this-is-a-very-long-path-name-with-more-than-20-chars(最後のコンポーネントは短縮されません: ソフト リミット)
  5. /home/user1/srcになります~/src($HOME は常に短縮されます)
  6. /home/user1/.kde4/share/config/kresourcesになります~/.k/s/c/kresources(接頭辞のドットが保持されることに注意してください)

現在のユーザーは user1 です。

awkperl、などの外部インタープリターを呼び出すことはできますがrubypythonコンパイルされた C プログラムなどを呼び出すことはできません。つまり、外部ソース ファイルは許可されず、コードはインラインである必要があります。最短バージョンが勝ちます。bash 関数本体 (および呼び出されたサブ関数) の長さは、次のことを意味します。

_sub_helper() {
  # this counts
}
_dir_chomp() {
  # these characters count (between { and })
  _sub_helper "foobar" # _sub_helper body counts, too
}
4

5 に答える 5

13

ピュアバッシュ:

_dir_chomp () {
    local IFS=/ c=1 n d
    local p=(${1/#$HOME/\~}) r=${p[*]}
    local s=${#r}
    while ((s>$2&&c<${#p[*]}-1))
    do
        d=${p[c]}
        n=1;[[ $d = .* ]]&&n=2
        ((s-=${#d}-n))
        p[c++]=${d:0:n}
    done
    echo "${p[*]}"
}

テストの目的で、質問は現在のユーザーが「user1」であることを意味していると想定しています。

注: Bash 4 には、PROMPT_DIRTRIM\wPS1応じてサブディレクトリの数を保持し、残りを...

/$ PROMPT_DIRTRIM=2
/$ echo $PS1
\w\$
/$ pwd
/
/$ cd /usr/share/doc/bash
.../doc/bash$
于 2010-08-17T02:30:33.937 に答える
8

これは私の他の答えよりも20文字ほど短いです:

_dir_chomp () {
    local p=${1/#$HOME/\~} b s
    s=${#p}
    while [[ $p != "${p//\/}" ]]&&(($s>$2))
    do
        p=${p#/}
        [[ $p =~ \.?. ]]
        b=$b/${BASH_REMATCH[0]}
        p=${p#*/}
        ((s=${#b}+${#p}))
    done
    echo ${b/\/~/\~}${b+/}$p
}
于 2010-08-17T04:02:06.930 に答える
1

これは、この課題のアイデアを思いついたときの私自身の解決策でした。インスピレーションは、実際にJolexa のブログから得ました。

これが、読み取り可能な形式の Ruby 実装です。

a = ARGV[1].gsub(%r{^#{ENV['HOME']}}, "~")
b, a = a, a.gsub(%r{/(\.?[^/.])[^/]+(/.*)}, '/\1\2') while
  (a.length > ARGV[2].to_i) && (b != a)
print a

そして、bash 関数内の実際の 1 行の実装:

_dir_chomp() {
  ruby -e'a="'$1'".gsub(%r{^'$HOME'},"~");b,a=a,a.gsub(%r{/(\.?[^/.])[^/]+(/.*)},"/\\1\\2")while(a.length>'$2')&&(b!=a);print a'
}
于 2010-08-17T07:46:40.257 に答える
-1

これは、タイトルバーにフルパスを付けてbashプロンプトを短縮する方法です(3.0以降で機能します):

_PS1P=('' '..')
PROMPT_COMMAND='_PS1L=${#DIRSTACK[0]} _PS1D=${DIRSTACK[0]}'
PS1='\[\e]2;\h:\w\a\]\h ${_PS1P[$_PS1L>36]}${_PS1D:$_PS1L>36?-34:0} \$ '

この方法では、必要な CPU オーバーヘッドが非常に低くなります。

于 2014-09-20T16:16:49.083 に答える