<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 coreutils
macOS를 사용하는 경우 다음 을 통해 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