Elimina barras innecesarias de una ruta determinada con bash

How can I get rid of unnecessary slashes in a given path?

Ejemplo:

p="/foo//////bar///hello/////world"

Yo quiero:

p="/foo/bar/hello/world"

preguntado el 09 de enero de 11 a las 11:01

8 Respuestas

Utilización de readlink:

p=$(readlink -m "/foo//////bar///hello/////world")

Notice that this will canonicalize symbolic links. If that's not what you want, use SED:

p=$(echo "/foo//////bar///hello/////world" | sed s#//*#/#g)

Respondido el 09 de enero de 11 a las 15:01

Could use readlink -m instead, and the directory doesn't need to exist. - Ryan Li

@Ryan Li Thanks, that's indeed way better. Updated. - Phihag

Thanks. I already tried sed 's/\/\//\//g' which doesnt worked in the way I want. - Casper

Using pure Bash:

shopt -s extglob
echo ${p//\/*(\/)/\/}

Respondido el 09 de enero de 11 a las 17:01

With realpath:

realpath -sm $p

parámetros:

  -m, --canonicalize-missing   no components of the path need exist
  -s, --strip, --no-symlinks   don't expand symlinks

Respondido el 11 de enero de 17 a las 13:01

your input:

p="/foo//////bar///hello/////world"

command to remove the irrelevant slashes:

echo $p | tr -s /

salida:

/foo/bar/hello/world

Respondido 10 Feb 18, 01:02

this is definitely my favorite solution to the problem. Just for reference here are 2 additional ones using sed: echo $p | sed -r 's|/+|/|g' or echo $p | sed 's|//*|/|g' - Cripton

Very cool option of tr -s / --squeeze-repeats to squeeze all repeated character into one. Thanks the shortest solution! - Noam Manos

  1. Consider if you need to do this. On Unix, specifying duplicate path separators (and even things like /foo/.//bar///hello/./world funciona bien
  2. Puedes usar readlink -f, but this will also canonicalize the symlinks in that path, so the result depends on your filesystem and the path supplied must actually exist, so this won't work for virtual paths.

Respondido el 09 de enero de 11 a las 15:01

most of the time, extra slashes work fine, but in some cases they cause problems (I once had this with an rsync option not working correctly if the path had doubles slashes) - Steabert

This works with multiple separators and does not assume the given path should exist:

p=/foo///.//bar///foo1/bar1//foo2/./bar2; 
echo $p | awk '{while(index($1,"/./")) gsub("/./","/"); while(index($1,"//"))
     gsub("//","/");  print $1;}'

But does not simplify well strings containing ".."

Respondido el 06 de junio de 13 a las 02:06

En zsh:

echo "${p:a}"

Works with non-existent paths, too.

Respondido 29 Jul 20, 10:07

Thanks for the replys. I know the path works fine. I just want this for optical reasons.

Encontré otra solución: echo $p | replace '//' ''

Respondido el 09 de enero de 11 a las 15:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.