sintaxis saber rutas ruta relativas relativa para obtener nombre ejercicios ejemplos comandos comando basicos archivo absolutas absoluta bash shell path absolute

bash - saber - ruta absoluta y relativa linux



Bash: recupera la ruta absoluta dada relativa (15)

Creo que este es el más portátil:

abspath() { cd "$(dirname "$1")" printf "%s/%s/n" "$(pwd)" "$(basename "$1")" cd "$OLDPWD" }

Sin embargo, fallará si la ruta no existe.

¿Hay un comando para recuperar la ruta absoluta dada la ruta relativa?

Por ejemplo, quiero que $ line contenga la ruta absoluta de cada archivo en dir ./etc/

find ./ -type f | while read line; do echo $line done


De manera similar a la respuesta de @ ernest-a, pero sin afectar $OLDPWD o definir una nueva función, podría $OLDPWD una subshell (cd <path>; pwd)

$ pwd /etc/apache2 $ cd ../cups $ cd - /etc/apache2 $ (cd ~/..; pwd) /Users $ cd - /etc/cups


En caso de find , probablemente sea más fácil dar la ruta absoluta para buscar, por ejemplo:

find /etc find `pwd`/subdir_of_current_dir/ -type f


La respuesta de Eugen no funcionó para mí, pero lo hizo:

absolute="$(cd $(dirname $file); pwd)/$(basename $file)"

Nota al margen, su directorio de trabajo actual no se ve afectado.


Lo que dijeron, excepto find $PWD o (en bash) find ~+ es un poco más conveniente.


Por lo que vale, voté por la respuesta que se eligió, pero quería compartir una solución. La desventaja es que solo es Linux: pasé unos 5 minutos tratando de encontrar el equivalente OSX antes de llegar al desbordamiento de la pila. Estoy seguro de que está ahí fuera.

En Linux puede usar readlink -e en tándem con dirname .

$(dirname $(readlink -e ../../../../etc/passwd))

rendimientos

/etc/

Y luego usa la hermana de dirname , basename para obtener el nombre de archivo

$(basename ../../../../../passwd)

rendimientos

passwd

Ponlo todo junto..

F=../../../../../etc/passwd echo "$(dirname $(readlink -e $F))/$(basename $F)"

rendimientos

/etc/passwd

Estás seguro si estás apuntando a un directorio, el basename arrojará nada y terminarás con doble barra en el resultado final.



Si desea transformar una variable que contiene una ruta relativa en una ruta absoluta, esto funciona:

dir=`cd "$dir"`

"cd" se repite sin cambiar el directorio de trabajo, porque se ejecuta aquí en un subconjunto.


Si está utilizando bash en Mac OS X que no tiene realpath ni su readlink puede imprimir la ruta absoluta, puede tener otra opción que codificar su propia versión para imprimirla. Aquí está mi implementación:

(puro bash)

abspath(){ local thePath if [[ ! "$1" =~ ^/ ]];then thePath="$PWD/$1" else thePath="$1" fi echo "$thePath"|( IFS=/ read -a parr declare -a outp for i in "${parr[@]}";do case "$i" in ''''|.) continue ;; ..) len=${#outp[@]} if ((len==0));then continue else unset outp[$((len-1))] fi ;; *) len=${#outp[@]} outp[$len]="$i" ;; esac done echo /"${outp[*]}" ) }

(use gawk)

abspath_gawk() { if [[ -n "$1" ]];then echo $1|gawk ''{ if(substr($0,1,1) != "/"){ path = ENVIRON["PWD"]"/"$0 } else path = $0 split(path, a, "/") n = asorti(a, b,"@ind_num_asc") for(i in a){ if(a[i]=="" || a[i]=="."){ delete a[i] } } n = asorti(a, b, "@ind_num_asc") m = 0 while(m!=n){ m = n for(i=1;i<=n;i++){ if(a[b[i]]==".."){ if(b[i-1] in a){ delete a[b[i-1]] delete a[b[i]] n = asorti(a, b, "@ind_num_asc") break } else exit 1 } } } n = asorti(a, b, "@ind_num_asc") if(n==0){ printf "/" } else { for(i=1;i<=n;i++){ printf "/"a[b[i]] } } }'' fi }

(puro bsd awk)

#!/usr/bin/env awk -f function abspath(path, i,j,n,a,b,back,out){ if(substr(path,1,1) != "/"){ path = ENVIRON["PWD"]"/"path } split(path, a, "/") n = length(a) for(i=1;i<=n;i++){ if(a[i]==""||a[i]=="."){ continue } a[++j]=a[i] } for(i=j+1;i<=n;i++){ delete a[i] } j=0 for(i=length(a);i>=1;i--){ if(back==0){ if(a[i]==".."){ back++ continue } else { b[++j]=a[i] } } else { if(a[i]==".."){ back++ continue } else { back-- continue } } } if(length(b)==0){ return "/" } else { for(i=length(b);i>=1;i--){ out=out"/"b[i] } return out } } BEGIN{ if(ARGC>1){ for(k=1;k<ARGC;k++){ print abspath(ARGV[k]) } exit } } { print abspath($0) }

ejemplo:

$ abspath I/am/.//..//the/./god/../of///.././war /Users/leon/I/the/war


Si la ruta relativa es una ruta de directorio, entonces prueba la mía, debería ser la mejor:

absPath=$(pushd ../SOME_RELATIVE_PATH_TO_Directory > /dev/null && pwd && popd > /dev/null) echo $absPath


Si tiene instalado el paquete coreutils, generalmente puede usar readlink -f relative_file_name para recuperar el absoluto (con todos los enlaces simbólicos resueltos)


utilizar:

find $(pwd)/ -type f

para obtener todos los archivos o

echo $(pwd)/$line

para mostrar la ruta completa (si la ruta relativa es importante)


realpath es probablemente el mejor

Pero ...

La pregunta inicial fue muy confusa para empezar, con un ejemplo poco relacionado con la pregunta tal como se establece.

La respuesta seleccionada en realidad responde al ejemplo dado, y no a la pregunta en el título. El primer comando es esa respuesta (¿es realmente ?, lo dudo), y podría funcionar tan bien sin el ''/''. Y no puedo ver qué está haciendo el segundo comando.

Varios problemas son mixtos:

  • cambiando un nombre de ruta relativo a uno absoluto, lo que sea que denota, posiblemente nada. ( Por lo general, si emite un comando como touch foo/bar , el nombre de ruta foo/bar debe existir para usted, y posiblemente se use en el cálculo, antes de que realmente se cree el archivo ) .

  • puede haber varios nombres de ruta absolutos que denotan el mismo archivo (o posible archivo), especialmente debido a enlaces simbólicos (enlaces simbólicos) en la ruta, pero posiblemente por otros motivos (un dispositivo puede montarse dos veces como de solo lectura). Uno puede o no querer resolver explícitamente tales enlaces simbólicos.

  • llegar al final de una cadena de enlaces simbólicos a un archivo o nombre que no es un enlace simbólico. Esto puede generar o no un nombre de ruta absoluto, dependiendo de cómo se hace. Y uno puede, o no, querer resolverlo en una ruta de acceso absoluta.

El comando readlink foo without option da una respuesta solo si su argumento foo es un enlace simbólico, y esa respuesta es el valor de ese enlace simbólico. No se sigue ningún otro enlace. La respuesta puede ser una ruta relativa: cualquiera que sea el valor del argumento de enlace simbólico.

Sin embargo, readlink tiene opciones (-f -e o -m) que funcionarán para todos los archivos, y dan una ruta de acceso absoluta (la que no tiene enlaces simbólicos) al archivo realmente denotado por el argumento.

Esto funciona bien para cualquier cosa que no sea un enlace simbólico, aunque uno podría desear usar una ruta de acceso absoluta sin resolver los enlaces simbólicos intermedios en la ruta. Esto se hace mediante el comando realpath -s foo

En el caso de un argumento de enlace simbólico, readlink con sus opciones resolverá nuevamente todos los enlaces simbólicos en la ruta absoluta al argumento, pero eso también incluirá todos los enlaces simbólicos que puedan encontrarse al seguir el valor del argumento. Puede que no lo desee si desea una ruta de acceso absoluta al enlace simbólico en sí mismo, en lugar de a lo que pueda vincularse. Nuevamente, si foo es un enlace simbólico, realpath -s foo obtendrá una ruta absoluta sin resolver los enlaces simbólicos, incluido el que se da como argumento.

Sin la opción -s , realpath hace casi lo mismo que readlink , excepto simplemente leyendo el valor de un enlace, así como varias otras cosas. Simplemente no está claro para mí por qué readlink tiene sus opciones, creando aparentemente una redundancia indeseable con realpath .

Explorar la web no dice mucho más, excepto que puede haber algunas variaciones en los sistemas.

Conclusión: realpath es el mejor comando para usar, con la mayor flexibilidad, al menos para el uso que se solicita aquí.


#! /bin/sh echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"

UPD Algunas explicaciones

  1. Este script obtiene ruta relativa como argumento "$1"
  2. Luego, obtenemos el nombre del directorio como parte de esa ruta (puede pasar el directorio o el archivo a este script): dirname "$1"
  3. Luego, cd "$(dirname "$1") en este directorio relativo y obtenemos una ruta absoluta ejecutando el comando pwd shell
  4. Después de eso, agregamos basename a la ruta absoluta: $(basename "$1")
  5. Como paso final lo hacemos echo

echo "mydir/doc/ mydir/usoe ./mydir/usm" | awk ''{ split($0,array," "); for(i in array){ system("cd "array[i]" && echo $PWD") } }''