fork(1) download
  1. ### Please skip down to the bottom of this code
  2.  
  3. # Given a string, a separator, and a max length, shorten any segments that are
  4. # longer than the max length.
  5. shortenLongSegments() {
  6. local -n destVar=$1; shift # arg1: where do we write our result?
  7. local maxLength=$1; shift # arg2: what's the maximum length?
  8. local IFS=$1; shift # arg3: what character do we split into segments on?
  9. read -r -a allSegments <<<"$1"; shift # arg4: break into an array
  10.  
  11. for segmentIdx in "${!allSegments[@]}"; do # iterate over array indices
  12. segment=${allSegments[$segmentIdx]} # look up value for index
  13. if (( ${#segment} > maxLength )); then # value over maxLength chars?
  14. segment="${segment:0:3}*${segment:${#segment}-3:3}" # build a short version
  15. allSegments[$segmentIdx]=$segment # store shortened version in array
  16. fi
  17. done
  18. printf -v destVar '%s\n' "${allSegments[*]}" # build result string from array
  19. }
  20.  
  21. # function to call from PROMPT_COMMAND to actually build a new PS1
  22. buildNewPs1() {
  23. # declare our locals to avoid polluting global namespace
  24. local shorterPath
  25. # but to cache where we last ran, we need a global; be explicit.
  26. declare -g buildNewPs1_lastDir
  27. # do nothing if the directory hasn't changed
  28. [[ $PWD = "$buildNewPs1_lastDir" ]] && return 0
  29. shortenLongSegments shorterPath 10 / "$PWD"
  30. PS1="${shorterPath}\$"
  31. # update the global tracking where we last ran this code
  32. buildNewPs1_lastDir=$PWD
  33. }
  34.  
  35. sampleOne() {
  36. PS1=`echo ${PWD#"${PWD%/*/*}/"} | awk -v RS='/' 'length()<=10{printf $0"/"}; length()>10{printf "%s*%s/", substr($0,1,3), substr($0,length()-2,3)};'| tr -d "\n"; echo "#"`
  37. }
  38. time for ((i=0; i<100; i++ )); do sampleOne; done
  39.  
  40. sampleTwo() {
  41. buildNewPs1
  42. }
  43. time for ((i=0; i<100; i++ )); do sampleTwo; done
Success #stdin #stdout #stderr 0.27s 5456KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
real	0m0.354s
user	0m0.228s
sys	0m0.035s

real	0m0.003s
user	0m0.003s
sys	0m0.000s