Bash сокращение PWD

private void toolStripButton1_Click(object sender, EventArgs e)
    {
        FileDialog fDialog = new OpenFileDialog();
        fDialog.CheckFileExists = true;
        fDialog.CheckPathExists = true;
        fDialog.RestoreDirectory = true;
        fDialog.Title = "Choose file to import";
        if (fDialog.ShowDialog() == DialogResult.OK)
        {
            string lstrFile = fDialog.FileName;
            Bitmap myBitmap = new Bitmap(lstrFile);
            // Copy the bitmap to the clipboard.
            Clipboard.SetDataObject(myBitmap);
            DataFormats.Format format = DataFormats.GetFormat(DataFormats.Bitmap);
            // After verifying that the data can be pasted, paste
            if(top==true && this.rtTop.CanPaste(format))
            {
                rtTop.Paste(format);
            }
            if (btmLeft == true && this.rtBottomLeft.CanPaste(format))
            {
                rtBottomLeft.Paste(format);
            }
            if (btmCenter == true && this.rtBottomCenter.CanPaste(format))
            {
                rtBottomCenter.Paste(format);
            }
            if (btmRight == true && this.rtBottomRight.CanPaste(format))
            {
                rtBottomRight.Paste(format);
            }
        }
    }
21
задан 24 October 2009 в 01:23
поделиться

5 ответов

Как насчет сценария Python? Это сокращает сначала самые длинные имена каталогов, по одному символу за раз, пока они не достигнут своей целевой длины или не смогут получить путь короче. Он не укорачивает последний каталог в пути.

(Я начал писать это в простом сценарии оболочки, но, черт возьми, bash неприятен при манипуляциях со строками.)

#!/usr/bin/env python
import sys

try:
    path   = sys.argv[1]
    length = int(sys.argv[2])
except:
    print >>sys.stderr, "Usage: $0 <path> <length>"
    sys.exit(1)

while len(path) > length:
    dirs = path.split("/");

    # Find the longest directory in the path.
    max_index  = -1
    max_length = 3

    for i in range(len(dirs) - 1):
        if len(dirs[i]) > max_length:
            max_index  = i
            max_length = len(dirs[i])

    # Shorten it by one character.    
    if max_index >= 0:
        dirs[max_index] = dirs[max_index][:max_length-3] + ".."
        path = "/".join(dirs)

    # Didn't find anything to shorten. This is as good as it gets.
    else:
        break

print path

Пример вывода:

$ echo $DIR
/this/is/the/path/to/a/really/long/directory/i/would/like/shortened
$ ./shorten.py $DIR 70
/this/is/the/path/to/a/really/long/directory/i/would/like/shortened 
$ ./shorten.py $DIR 65
/this/is/the/path/to/a/really/long/direc../i/would/like/shortened
$ ./shorten.py $DIR 60
/this/is/the/path/to/a/re../long/di../i/would/like/shortened
$ ./shorten.py $DIR 55
/t../is/the/p../to/a/r../l../di../i/wo../like/shortened
$ ./shorten.py $DIR 50
/t../is/the/p../to/a/r../l../d../i/w../l../shortened
5
ответ дан 29 November 2019 в 06:17
поделиться

Не дает того же результата, но мой ~ / .bashrc содержит

_PS1 ()
{
    local PRE= NAME="$1" LENGTH="$2";
    [[ "$NAME" != "${NAME#$HOME/}" || -z "${NAME#$HOME}" ]] &&
        PRE+='~' NAME="${NAME#$HOME}" LENGTH=$[LENGTH-1];
    ((${#NAME}>$LENGTH)) && NAME="/...${NAME:$[${#NAME}-LENGTH+4]}";
    echo "$PRE$NAME"
}
PS1='\u@\h:$(_PS1 "$PWD" 20)\$ '

, который ограничивает отображаемый путь до 20 символов. Если путь превышает 20 символов, он будет отображаться как / ... d / like / сокращенный или ~ /.../ like / сокращенный .

35
ответ дан 29 November 2019 в 06:17
поделиться

Вот решение только для bash, которое может вам понравиться. Это сокращает каждую часть пути до самого короткого префикса, который все еще может быть заполнен табуляцией, и использует * вместо .. в качестве заполнителя.

#!/bin/bash

begin="" # The unshortened beginning of the path.
shortbegin="" # The shortened beginning of the path.
current="" # The section of the path we're currently working on.
end="${2:-$(pwd)}/" # The unmodified rest of the path.
end="${end#/}" # Strip the first /
shortenedpath="$end" # The whole path, to check the length.
maxlength="${1:-0}"

shopt -q nullglob && NGV="-s" || NGV="-u" # Store the value for later.
shopt -s nullglob    # Without this, anything that doesn't exist in the filesystem turns into */*/*/...

while [[ "$end" ]] && (( ${#shortenedpath} > maxlength ))
do
  current="${end%%/*}" # everything before the first /
  end="${end#*/}"    # everything after the first /

  shortcur="$current"
  shortcurstar="$current" # No star if we don't shorten it.

  for ((i=${#current}-2; i>=0; i--))
  do
    subcurrent="${current:0:i}"
    matching=("$begin/$subcurrent"*) # Array of all files that start with $subcurrent. 
    (( ${#matching[*]} != 1 )) && break # Stop shortening if more than one file matches.
    shortcur="$subcurrent"
    shortcurstar="$subcurrent*"
  done

  begin="$begin/$current"
  shortbegin="$shortbegin/$shortcurstar"
  shortenedpath="$shortbegin/$end"
done

shortenedpath="${shortenedpath%/}" # strip trailing /
shortenedpath="${shortenedpath#/}" # strip leading /

echo "/$shortenedpath" # Make sure it starts with /

shopt "$NGV" nullglob # Reset nullglob in case this is being used as a function.

Дайте ему длину в качестве первого аргумента, а путь в качестве необязательного второго аргумент. Если второй аргумент не указан, используется текущий рабочий каталог.

Это будет пытаться сократить до указанной длины. Если это невозможно, он просто дает кратчайший путь, который может дать.

С алгоритмической точки зрения это, вероятно, ужасно, но в конечном итоге оказывается довольно быстрым. (Ключ к быстрым сценариям оболочки - это избегать подоболочек и внешних команд, особенно во внутренних циклах.)

По замыслу, он сокращается только на 2 или более символов («hom *» - это столько же символов, сколько «home»).

Это не идеально.

15
ответ дан 29 November 2019 в 06:17
поделиться

Вот относительно простое решение для Perl. Это коротко достаточно, чтобы вы могли встроить его прямо в PS1, а чем вызов сценария. Это дает всем персонажам усеченных имен вместо замены на '.'


$ echo '/this/is/a/realy/long/path/id/like/shortened' |
 perl -F/ -ane 'print join( "/", map { $i++ < @F - 2 ?
 substr $_,0,3 : $_ } @F)'
/thi/is/a/rea/lon/pat/id/like/shortened

Я не сразу вижу хороший способ заменить символы на '.', но вот уродливый способ:


echo '/this/is/a/realy/long/path/id/like/shortened' |
 perl -F/ -ane 'print join( "/", map { m/(.)(.*)/;
 $_ = $1 . "." x (length $2 > 2 ? 2 : length $2 ) if $i++ < @F - 2; $_ } @F)'
/t../i./a/r../l../p../i./like/shortened
1
ответ дан 29 November 2019 в 06:17
поделиться

Я внес некоторые улучшения в код Эвана Кролла. Теперь он проверяет, начинается ли ваш путь с $ HOME и начинается ли сокращенный вариант с ~ / вместо / h * / u * /

#!/bin/bash

begin="" # The unshortened beginning of the path.
shortbegin="" # The shortened beginning of the path.
current="" # The section of the path we're currently working on.
end="${2:-$(pwd)}/" # The unmodified rest of the path.

if [[ "$end" =~ "$HOME" ]]; then
    INHOME=1
    end="${end#$HOME}" #strip /home/username from start of string
    begin="$HOME"      #start expansion from the right spot
else
    INHOME=0
fi

end="${end#/}" # Strip the first /
shortenedpath="$end" # The whole path, to check the length.
maxlength="${1:-0}"

shopt -q nullglob && NGV="-s" || NGV="-u" # Store the value for later.
shopt -s nullglob    # Without this, anything that doesn't exist in the filesystem turns into */*/*/...

while [[ "$end" ]] && (( ${#shortenedpath} > maxlength ))
do
  current="${end%%/*}" # everything before the first /
  end="${end#*/}"    # everything after the first /

  shortcur="$current"
  shortcurstar="$current" # No star if we don't shorten it.

  for ((i=${#current}-2; i>=0; i--)); do
    subcurrent="${current:0:i}"
    matching=("$begin/$subcurrent"*) # Array of all files that start with $subcurrent. 
    (( ${#matching[*]} != 1 )) && break # Stop shortening if more than one file matches.
    shortcur="$subcurrent"
    shortcurstar="$subcurrent*"
  done

  #advance
  begin="$begin/$current"
  shortbegin="$shortbegin/$shortcurstar"
  shortenedpath="$shortbegin/$end"
done

shortenedpath="${shortenedpath%/}" # strip trailing /
shortenedpath="${shortenedpath#/}" # strip leading /

if [ $INHOME -eq 1 ]; then
  echo "~/$shortenedpath" #make sure it starts with ~/
else
  echo "/$shortenedpath" # Make sure it starts with /
fi

shopt "$NGV" nullglob # Reset nullglob in case this is being used as a function.

Кроме того, вот некоторые функции, которые я добавил в свой файл .bashrc, чтобы уменьшить показанный путь оболочкой. Я не уверен, что редактирование $ PWD таким образом полностью безопасно, поскольку некоторые сценарии могут зависеть от действительной строки $ PWD, но до сих пор у меня не было проблем с периодическим использованием. Обратите внимание, что я сохранил приведенный выше сценарий как «shortdir» и поместил его в свой PATH.

function tinypwd(){
    PWD=`shortdir`
}

function hugepwd(){
    PWD=`pwd`
}

РЕДАКТИРОВАТЬ, 19 октября 2010 г.

Правильный способ создания псевдонимов в bash - это изменение переменной $ PS1 ; так анализируется приглашение. В БОЛЬШИНСТВЕ случаев (99% времени) текущий путь в строке приглашения обозначается как «\ w». Мы можем использовать sed, чтобы заменить это на shortdir , например:

#NOTE: trailing space before the closing double-quote (") is a must!!
function tinypwd(){                                                             
    PS1="$(echo $PS1 | sed 's/\\w/\`shortdir\`/g') "
}                                                                               

function hugepwd(){                                                             
    PS1="$(echo $PS1 | sed 's/[`]shortdir[`]/\\w/g') "                            
} 
9
ответ дан 29 November 2019 в 06:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: