Digamos que tengo una variable con una ruta release/linux/x86
y quiero la ruta relativa de un directorio diferente (es decir, ../../..
del directorio de trabajo actual), ¿cómo puedo obtenerla en un comando de shell (o posiblemente en GNU Make)?
No se requiere soporte de enlace suave.
Esta pregunta se ha modificado en gran medida según la respuesta aceptada para mejorar la terminología.
Respuesta1
Absolutamente no está claro el propósito de esto, pero esto hará exactamente lo que se solicitó, usandoruta real de GNU:
realpath -m --relative-to=release/linux/x86 .
../../..
realpath -m --relative-to=release///./linux/./x86// .
../../..
Respuesta2
Aquí hay una función de shell que devuelve una ruta relativa desde el directorio de origen al de destino usando solo manipulación de cadenas, a través de la expansión de parámetros de shell, sin acceso al disco o a la red. Sin nombre de ruta resolución está hecho.
Espera dos parámetros, directorio-origen y directorio-destino, ambos nombres de ruta canonicalizados absolutos y no vacíos, cualquiera de los cuales puede terminar /
en -, no es necesario que exista ninguno. Devuelve el resultado en la variable de shell $REPLY
como una ruta relativa desde el directorio de origen al directorio de destino sin el final /
, .
si es nulo.
El algoritmo es de una publicación de comp.unix.shell de 2005 que ahora ha ascendido aarchivo.org.
pnrelpath() {
set -- "${1%/}/" "${2%/}/" '' ## '/'-end to avoid mismatch
while [ "$1" ] && [ "$2" = "${2#"$1"}" ] ## reduce $1 to shared path
do set -- "${1%/?*/}/" "$2" "../$3" ## source/.. target ../relpath
done
REPLY="${3}${2#"$1"}" ## build result
# unless root chomp trailing '/', replace '' with '.'
[ "${REPLY#/}" ] && REPLY="${REPLY%/}" || REPLY="${REPLY:-.}"
}
Usar como
$ pnrelpath "$HOME" "$PWD"
projects/incubator/nspreon
$ pnrelpath "$PWD" "$gimpkdir"
../../../.config/GIMP
$ pnrelpath "$PWD" "$(cd "$dirnm" && pwd || false)"
# using cd to resolve, canonicalize ${dirnm}
o conURIestamos compartiendo scheme://authority
,
$ pnrelpath 'https://example.com/questions/123456/how-to' 'https://example.com/media'
../../../media
Actualizar2022-11-24
Omitir la while
declaración en la función anterior devolverá lo que realpath --relative-base
hace: una ruta relativa desde el directorio de origen al directorio de destino si el destino está en el origen o debajo de él; de lo contrario, una ruta absoluta. Se aplican condiciones previas y posteriores similares.
pnrelbase() {
set -- "${1%/}/" "${2%/}/" ## '/'-end to avoid mismatch
REPLY="${2#"$1"}" ## build result
# unless root chomp trailing '/', replace '' with '.'
[ "${REPLY#/}" ] && REPLY="${REPLY%/}" || REPLY="${REPLY:-.}"
}
(finalizar actualización)