Aquí hay una solución fiesta, sólo que te pueden gustar . Esto acorta cada parte de la ruta hasta el prefijo más corto que aún puede completarse con pestañas, y usa * en lugar de ... como relleno.
#!/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.
Dale la longitud como primer argumento, y la ruta como el segundo argumento opcional. Si no se proporciona un segundo argumento, usa el directorio de trabajo actual.
Esto intentará acortar por debajo de la longitud indicada. Si eso no es posible, solo da el camino más corto que puede dar.
Algorítmicamente hablando, esto es probablemente horrible, pero termina siendo bastante rápido. (La clave para los guiones de shell rápidos es evitar subcapas y comandos externos, especialmente en los bucles internos.)
Por diseño, solo se acorta en 2 o más caracteres ('hom *' tiene tantos caracteres como 'inicio') .
No es perfecto. Hay algunas situaciones en las que no se acortará tanto como sea posible, como si hay varios archivos cuyos nombres de archivos comparten un prefijo (si foobar1 y foobar2 existen, foobar3 no se acortará.)
Personalmente, tengo el prompt acaba de ser los dos directorios superiores, por lo que lo anterior se convertiría en 'li ke/acortado'. Yo uso ZSH, sin embargo, así que no sé cómo lo harías en bash. – pavpanchekha
@pavpanchekha 'pwd | sed -e "s |. */\ (. * /. * \) | \ 1 |" ' – polypus74
Y para usar en PS1, uno podría: función pwd_depth_limit_2 { if [" $ PWD "=" $ HOME "] then echo -n" ~ " else pwd | sed -e "s |. */\ (. * /. * \) | \ 1 |" fi } – polypus74