¿Cómo quitar la última barra de la ruta del directorio?

17

Tengo un script que requiere un directorio como un argumento. Quiero apoyar las dos formas: una es como

a/b/c

(sin barra al final) y otro es como

 a/b/c/

(tiene una barra al final).

Mi pregunta: dada cualquiera de las dos formas, ¿cómo puedo mantener la primera forma sin cambios y quitar la última barra diagonal de la segunda forma para convertirla en la primera forma?

Yulong Ao
fuente
2
No es que deba ser un gran problema: una doble barra en cualquier lugar, excepto al comienzo, es equivalente a una sola barra, así que no se preocupe por unirlos usando /.
muru
@muru No sabía esto antes :).
Yulong Ao
Aquí hay un buen Q / A sobre separadores de ruta consecutivos múltiples
Peter
1
@muru Una barra al final puede marcar la diferencia, como la diferencia entre actuar en un enlace simbólico y actuar en el directorio al que apunta, o el argumento fuente de rsync.
Gilles 'SO- deja de ser malvado'
@Gilles de hecho, pero como puedes ver, estoy hablando de unir caminos.
muru

Respuestas:

23
dir=${1%/}

tomará el primer parámetro de la secuencia de comandos y eliminará una barra inclinada final si hay una.

Glenn Jackman
fuente
12

Para eliminar una barra inclinada final si hay una, puede usar la construcción de expansión del parámetro de eliminación de sufijo presente en todos los shells de estilo POSIX:

x=${x%/}

Hay algunas complicaciones. Esto solo elimina una barra oblicua, así que si comenzaste a/b/c//, terminarás con una barra oblicua. Además, si la ruta original era /, debe mantener la barra diagonal. Aquí hay una solución más compleja que se ocupa de estos casos:

case $x in
  *[!/]*/) x=${x%"${x##*[!/]}"};;
  *[/]) x="/";;
esac

Alternativamente, en ksh o en bash after shopt -s extglob:

[[ x = *[!/] ]] || x=${x%%*(/)}

Tenga en cuenta que en muchos casos, no importa que haya una barra inclinada final. Importa si el argumento es un enlace simbólico a un directorio: con una barra inclinada final, el argumento designa el directorio, mientras que sin una barra inclinada final, el argumento designa el enlace simbólico mismo. También es importante con algunos otros programas, por ejemplo, el argumento de origen rsyncse trata de manera diferente dependiendo de la presencia de una barra inclinada final.

Gilles 'SO- deja de ser malvado'
fuente
2

realpathresuelve el camino dado. Entre otras cosas, también elimina las barras diagonales finales. Se usa -spara evitar los siguientes enlaces sim.

DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a
Czerny
fuente