두 경로 사이의 상대 링크 가져오기

두 경로 사이의 상대 링크 가져오기

<source_path>와 의 두 가지 경로가 있다고 가정해 보겠습니다 <target_path>. 내 쉘(zsh)이 상대 경로로 <target_path>나타낼 수 있는 방법이 있는지 자동으로 파악하기를 원합니다 .<source_path>

예를 들어,

  • <source_path>/foo/bar/something
  • <target_path>/foo/hello/world

결과는 다음과 같습니다../../hello/world

왜 이것이 필요합니까?

다음을 사용하여 <source_path>심볼릭 링크를 만들어야 합니다.<target_path>비교적가능하면 심볼릭 링크를 사용하십시오. 그렇지 않으면 Windows에서 네트워크에 있는 이러한 파일에 액세스할 때 삼바 서버가 파일을 올바르게 표시하지 않습니다. (저는 시스템 관리자가 아니며 이 설정을 제어할 수 없습니다.)

<target_path>과 가 절대 경로라고 가정하면 <source_path>다음은 심볼릭 링크를 생성합니다.절대 경로를 가리킴.

ln -s <target_path> <source_path>

그래서 그것은 내 요구를 충족시키지 못합니다. 수백 개의 파일에 대해 이 작업을 수행해야 하므로 수동으로 수정할 수 없습니다.

이를 처리할 수 있는 쉘 내장 기능이 있습니까?

답변1

사용해 보세요realpath주문하다(GNU의 일부 coreutils;>=8.23),예를 들어:

realpath --relative-to=/foo/bar/something /foo/hello/world

brew install coreutilsmacOS를 사용하는 경우 다음 을 통해 GNU 버전을 설치하고 grealpath.

명령이 성공하려면 두 경로가 모두 존재해야 합니다. 상대 경로가 필요하더라도 그 중 하나가 존재하지 않더라도 -m 스위치를 추가하십시오.

더 많은 예를 보려면 다음을 참조하세요.현재 디렉터리가 주어지면 절대 경로를 상대 경로로 변환합니다..

답변2

symlinks다음 명령을 사용하여 절대 경로를 상대 경로로 변환 할 수 있습니다 .

/tmp$ mkdir -p 1/{a,b,c} 2
/tmp$ cd 2
/tmp/2$ ln -s /tmp/1/* .
/tmp/2$ ls -l
total 0
lrwxrwxrwx 1 stephane stephane 8 Jul 31 16:32 a -> /tmp/1/a/
lrwxrwxrwx 1 stephane stephane 8 Jul 31 16:32 b -> /tmp/1/b/
lrwxrwxrwx 1 stephane stephane 8 Jul 31 16:32 c -> /tmp/1/c/

이미 절대 링크가 있으므로 이를 상대 링크로 변환해 보겠습니다.

/tmp/2$ symlinks -cr .
absolute: /tmp/2/a -> /tmp/1/a
changed:  /tmp/2/a -> ../1/a
absolute: /tmp/2/b -> /tmp/1/b
changed:  /tmp/2/b -> ../1/b
absolute: /tmp/2/c -> /tmp/1/c
changed:  /tmp/2/c -> ../1/c
/tmp/2$ ls -l
total 0
lrwxrwxrwx 1 stephane stephane 6 Jul 31 16:32 a -> ../1/a/
lrwxrwxrwx 1 stephane stephane 6 Jul 31 16:32 b -> ../1/b/
lrwxrwxrwx 1 stephane stephane 6 Jul 31 16:32 c -> ../1/c/

인용하다

답변3

내 생각에 이 파이썬 솔루션은이 답변)도 언급할 가치가 있다. 다음 항목에 추가하세요 ~/.zshrc.

relpath() python -c 'import os.path, sys;\
  print os.path.relpath(sys.argv[1],sys.argv[2])' "$1" "${2-$PWD}"

그러면 다음과 같이 할 수 있습니다:

$ relpath /usr/local/share/doc/emacs /usr/local/share/fonts
../doc/emacs

답변4

# Prints out the relative path between to absolute paths. Trivial.
#
# Parameters:
# $1 = first path
# $2 = second path
#
# Output: the relative path between 1st and 2nd paths
relpath() {
    local pos="${1%%/}" ref="${2%%/}" down=''

    while :; do
        test "$pos" = '/' && break
        case "$ref" in $pos/*) break;; esac
        down="../$down"
        pos=${pos%/*}
    done

    echo "$down${ref##$pos/}"
}

이것이 문제를 해결하는 가장 간단하고 아름다운 방법입니다.

또한 Bourne과 같은 모든 쉘에서도 작동해야 합니다.

여기에 지혜가 있습니다. 외부 유틸리티나 복잡한 조건이 전혀 필요하지 않습니다. Bourne과 같은 쉘에서 무엇이든 수행하는 데 필요한 것은 몇 가지 접두사/접미사 대체와 while 루프뿐입니다.

PasteBin을 통해서도 사용 가능:http://pastebin.com/CtTfvime

관련 정보