programing

명령 줄 프롬프트의 현재 디렉터리를 줄이려면 어떻게해야합니까?

sourcetip 2021. 1. 16. 11:14
반응형

명령 줄 프롬프트의 현재 디렉터리를 줄이려면 어떻게해야합니까?


나는 Ubuntu를 사용하고 있으며 깊은 디렉토리 계층 구조로 작업 할 때 bash 에서이 긴 프롬프트에 지쳤습니다. 따라서 작업 디렉토리 부분을 다음과 같이 줄 이도록 PS1을 조정하고 싶습니다.

현재 나는 :

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

다음을 갖고 싶습니다.

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

len ($ PWD)가 주어진 임계 값을 통과하면 잘림이 발생합니다. 항상 첫 번째 경로 구성 요소와 하나 이상의 마지막 경로 구성 요소를 유지하고 싶습니다. 그런 다음 공간이 허용되면 오른쪽에서 가져 오는 구성 요소를 더 추가하십시오.

이것이 제가 현재 가지고있는 것입니다. 작동하지만 : 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$ 

미리 감사드립니다!


귀하의 경우에 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/testPS1을 다음과 같이 만듭니다.~/workspace/.../folder1/test

최신 정보

위의 솔루션은 프롬프트를 설정하지만 귀하의 의견에서 언급했듯이 디렉토리를 변경할 때 PS1을 동적으로 변경하지 않습니다. 여기에 디렉토리를 변경할 때 PS1을 동적으로 설정하는 솔루션이 있습니다.

.bashrc 파일에 다음 두 줄을 넣으십시오.

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}")$ '

if (NF > 4 && length($0) > 14)awk의 조건은 현재 디렉토리가 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 ..
~$

디렉토리를 변경할 때 프롬프트가 어떻게 변경되는지 확인하십시오. 이것이 당신이 원했던 것이 아니라면 알려주세요.


훨씬 더 간단한 솔루션을 찾고 경로의 첫 번째 디렉토리 이름이 필요하지 않은 사람들을 위해 Bash는 PROMPT_DIRTRIM변수를 사용하여 기본적으로 지원 합니다. 문서에서 :

PROMPT_DIRTRIM

0보다 큰 숫자로 설정하면 \ 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.


이것은 anubhava의 솔루션을 기반으로 사용하는 것입니다. 프롬프트와 창 제목을 모두 설정합니다. awk 스크립트는 더 읽기 쉬워서 쉽게 조정 / 사용자 정의 할 수 있습니다.

16 자 이상이고 4 단계 깊이 인 경우 경로를 접습니다. 또한 ...에 얼마나 많은 디렉토리가 접혔는지 표시하므로 경로가 얼마나 깊은 지 알 수 있습니다. 즉, ~/usr/..4../path2/path14 개의 레벨이 접 혔음을 나타냅니다.

# 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은 마지막 명령의 리턴 코드입니다.

여기에 이미지 설명 입력


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

편의를 위해서만 -r을 사용하여 sed, 괄호 앞의 백 슬래시를 생략 할 수 있으며 "|" 편의를 위해서만 구분 기호로 사용합니다. 명령 안에 슬래시를 사용하고 싶기 때문입니다. 나는 당신의 집이 ~로 표시되어 있다고 생각하므로 ~ / foo / bar / baz /는 ~ / foo /.../ baz로 끝나야하고 / foo / bar / baz /는 /foo/.../baz로 끝나야합니다. /.

그래서 우리는 선택적인 ~를 취하고, 그 뒤에 슬래시, 이름, 슬래시를 \ 1, 그 다음에 무언가를 취하고 나머지는 \ 2로합니다.


또 다른 방법은, 여전히 사용 sed하고 awk프롬프트를 생성합니다. 그러면 $HOME디렉토리가 ~ 로 변환 되고 루트 디렉토리, 최하위 레벨 (현재 디렉토리) 및 상위 ..디렉토리가 각 디렉토리별로 구분되어 표시됩니다 .

내부 .bashrc(또는 .bash_profileOS X) :

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/ ->

Apart from the bash-builtin solution using PROMPT_DIRTRIM, you may want to try $(pwd | tail -c16), which is a tad simpler than most other answers, but just gives the last 16 characters of the current directory. Of course replace 16 by any number you want.


Why not just use ${string:position:length}? You can do ${string:-$max_chars} to have the last ${max_chars} of the string.

note the negative value


Not so different from previous solutions. However, maybe a bit more readable/editable. However, no solution to the folder name boundary, only focusing on the length of the prompt.

### 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

added to the .bashrc file. All parts of the prompt is updated properly. The first part is shortened if you're in your home directory. Example:

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


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}"
}

export PS1

PS1="\$(generatePwd)"

Console

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

https://github.com/chrissound/SodiumSierraStrawberry

다음과 같은 경로를자를 수 있습니다.

보낸 사람 : / home / sodium / Projects / Personal / Sierra / Super / Long / Path / HolyAvacado

받는 사람 :»Projects / Sie… / Sup… / Lon… / Pat… / HolyAvacado /

참조 URL : https://stackoverflow.com/questions/5687446/how-can-i-shortern-my-command-line-prompts-current-directory

반응형