una rutas ruta relativas relativa qué entre ejercicios diferencia archivo acceso absolutas absoluta perl unix shell path absolute-path

perl - rutas - Convirtiendo ruta relativa en ruta absoluta?



rutas relativas arcgis (6)

Usando bash

# Directory relative_dir="folder/subfolder/" absolute_dir="$( cd "$relative_dir" && pwd )" # File relative_file="folder/subfolder/file" absolute_file="$( cd "${relative_file%/*}" && pwd )"/"${relative_file##*/}"

  • ${relative_file%/*} es el mismo resultado que dirname "$relative_file"
  • ${relative_file##*/} es el mismo resultado que el basename "$relative_file"

Advertencias : No resuelve enlaces simbólicos (es decir, no canonicaliza la ruta) => No puede diferenciar todos los duplicados si usa enlaces simbólicos.

Usando realpath

Command realpath hace el trabajo. Una alternativa es usar readlink -e (o readlink -f ). Sin embargo, realpath no suele estar instalado por defecto. Si no puede estar seguro de que realpath o readlink están presentes, puede sustituirlo utilizando perl (consulte a continuación).

Usando perl

Steven Kramer propone un alias de shell si realpath no está disponible en su sistema:

$ alias realpath="perl -MCwd -e ''print Cwd::realpath(/$ARGV[0]),qq</n>''" $ realpath path/folder/file /home/user/absolute/path/folder/file

o si prefiere usar perl directamente:

$ perl -MCwd -e ''print Cwd::realpath($ARGV[0]),qq</n>'' path/folder/file /home/user/absolute/path/folder/file

Este comando de una línea perl utiliza Cwd::realpath . De hecho, hay tres funciones perl. Toman un solo argumento y devuelven el nombre de ruta absoluto. Los detalles a continuación son de la documentación Perl5> Módulos principales> Cwd .

  • abs_path() usa el mismo algoritmo que getcwd() . Los enlaces simbólicos y los componentes de la ruta relativa ( . Y .. ) se resuelven para devolver el nombre de ruta canónico, al igual que en el realpath .

    use Cwd ''abs_path''; my $abs_path = abs_path($file);

  • realpath() es un sinónimo de abs_path()

    use Cwd ''realpath''; my $abs_path = realpath($file);

  • fast_abs_path() es una versión más peligrosa, pero potencialmente más rápida de abs_path()

    use Cwd ''fast_abs_path''; my $abs_path = fast_abs_path($file);

Estas funciones se exportan solo en request =>, por lo tanto, use Cwd para evitar el error de "subrutina no arielf " como se arielf por arielf . Si desea importar todas estas tres funciones, puede usar una línea use Cwd un solo use Cwd :

use Cwd qw(abs_path realpath fast_abs_path);

No estoy seguro si estas rutas son duplicadas. Dada la ruta relativa, ¿cómo puedo determinar la ruta absoluta usando un script de shell?

Ejemplo:

relative path: /x/y/../../a/b/z/../c/d absolute path: /a/b/c/d


Como me he encontrado con esto muchas veces a lo largo de los años, y esta vez necesitaba una versión portátil de bash pura que pudiera usar en OSX y Linux, continué y escribí una:

La versión viva vive aquí:

https://github.com/keen99/shell-functions/tree/master/resolve_path

pero por el bien de SO, aquí está la versión actual (creo que está bien probado ... ¡pero estoy abierto a comentarios!)

Puede que no sea difícil hacer que funcione para bourne shell (sh), pero no lo intenté ... me gusta demasiado $ FUNCNAME. :)

#!/bin/bash resolve_path() { #I''m bash only, please! # usage: resolve_path <a file or directory> # follows symlinks and relative paths, returns a full real path # local owd="$PWD" #echo "$FUNCNAME for $1" >&2 local opath="$1" local npath="" local obase=$(basename "$opath") local odir=$(dirname "$opath") if [[ -L "$opath" ]] then #it''s a link. #file or directory, we want to cd into it''s dir cd $odir #then extract where the link points. npath=$(readlink "$obase") #have to -L BEFORE we -f, because -f includes -L :( if [[ -L $npath ]] then #the link points to another symlink, so go follow that. resolve_path "$npath" #and finish out early, we''re done. return $? #done elif [[ -f $npath ]] #the link points to a file. then #get the dir for the new file nbase=$(basename $npath) npath=$(dirname $npath) cd "$npath" ndir=$(pwd -P) retval=0 #done elif [[ -d $npath ]] then #the link points to a directory. cd "$npath" ndir=$(pwd -P) retval=0 #done else echo "$FUNCNAME: ERROR: unknown condition inside link!!" >&2 echo "opath [[ $opath ]]" >&2 echo "npath [[ $npath ]]" >&2 return 1 fi else if ! [[ -e "$opath" ]] then echo "$FUNCNAME: $opath: No such file or directory" >&2 return 1 #and break early elif [[ -d "$opath" ]] then cd "$opath" ndir=$(pwd -P) retval=0 #done elif [[ -f "$opath" ]] then cd $odir ndir=$(pwd -P) nbase=$(basename "$opath") retval=0 #done else echo "$FUNCNAME: ERROR: unknown condition outside link!!" >&2 echo "opath [[ $opath ]]" >&2 return 1 fi fi #now assemble our output echo -n "$ndir" if [[ "x${nbase:=}" != "x" ]] then echo "/$nbase" else echo fi #now return to where we were cd "$owd" return $retval }

he aquí un ejemplo clásico, gracias a brew:

%% ls -l `which mvn` lrwxr-xr-x 1 draistrick 502 29 Dec 17 10:50 /usr/local/bin/mvn@ -> ../Cellar/maven/3.2.3/bin/mvn

usa esta función y devolverá la ruta real -real:

%% cat test.sh #!/bin/bash . resolve_path.inc echo echo "relative symlinked path:" which mvn echo echo "and the real path:" resolve_path `which mvn` %% test.sh relative symlinked path: /usr/local/bin/mvn and the real path: /usr/local/Cellar/maven/3.2.3/libexec/bin/mvn


De esta fuente viene:

#!/bin/bash # Assume parameter passed in is a relative path to a directory. # For brevity, we won''t do argument type or length checking. ABS_PATH=`cd "$1"; pwd` # double quotes for paths that contain spaces etc... echo "Absolute path: $ABS_PATH"

También puede hacer un trazador de líneas Perl, por ejemplo, usando Cwd::abs_path


Echa un vistazo a ''realpath''.

$ realpath usage: realpath [-q] path [...] $ realpath ../../../../../ /data/home


El método más confiable que he encontrado en Unix es readlink -f :

$ readlink -f /x/y/../../a/b/z/../c/d /a/b/c/d

Un par de advertencias:

  1. Esto también tiene el efecto secundario de resolver todos los enlaces simbólicos. Esto puede o no ser deseable, pero generalmente lo es.
  2. readlink dará un resultado en blanco si hace referencia a un directorio no existente. Si desea admitir rutas que no existen, utilice readlink -m lugar. Lamentablemente, esta opción no existe en versiones de readlink publicadas antes de ~ 2005.

Puede ser que esto ayude:

$path = "~user/dir/../file" $resolvedPath = glob($path); # (To resolve paths with ''~'') # Since glob does not resolve relative path, we use abs_path $absPath = abs_path($path);