상대 경로를 절대 경로로 변환 하시겠습니까?
이 경로가 중복되는지 확실하지 않습니다. 상대 경로가 주어지면 쉘 스크립트를 사용하여 절대 경로를 어떻게 결정합니까?
예:
relative path: /x/y/../../a/b/z/../c/d
absolute path: /a/b/c/d
에서 이 소스가 온다 :
#!/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"
예를 들어 Cwd::abs_path
내가 유닉스에서 만난 가장 신뢰할 수있는 방법은 readlink -f
다음과 같습니다.
$ readlink -f /x/y/../../a/b/z/../c/d
/a/b/c/d
몇 가지주의 사항 :
- 이것은 또한 모든 심볼릭 링크를 해결하는 부작용이 있습니다. 이것은 바람직하거나 바람직하지 않을 수 있지만 일반적으로 그렇습니다.
readlink
존재하지 않는 디렉토리를 참조하면 빈 결과가 표시됩니다. 존재하지 않는 경로를 지원하려면readlink -m
대신 사용하십시오. 불행히도이 옵션은 2005 년 이전에 출시 된 readlink 버전에는 존재하지 않습니다.
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%/*}
다음과 같은 결과입니다.dirname "$relative_file"
${relative_file##*/}
다음과 같은 결과입니다.basename "$relative_file"
주의 사항 : 심볼릭 링크를 해결하지 않습니다 (예 : 경로를 정규화하지 않음) => 심볼릭 링크를 사용하는 경우 모든 중복을 구별하지 못할 수 있습니다.
사용 realpath
명령 realpath
이 일을합니다. 대안은 readlink -e
(또는 readlink -f
) 을 사용하는 것입니다 . 그러나 realpath
기본적으로 자주 설치되지는 않습니다. 확실하지 realpath
않거나 readlink
존재하는 경우 perl을 사용하여 대체 할 수 있습니다 (아래 참조).
Perl 사용
Steven Kramerrealpath
는 시스템에서 사용할 수없는 경우 쉘 별칭을 제안 합니다.
$ alias realpath="perl -MCwd -e 'print Cwd::realpath(\$ARGV[0]),qq<\n>'"
$ realpath path/folder/file
/home/user/absolute/path/folder/file
또는 직접 펄 사용을 선호하는 경우 :
$ perl -MCwd -e 'print Cwd::realpath($ARGV[0]),qq<\n>' path/folder/file
/home/user/absolute/path/folder/file
이 한 줄짜리 perl 명령은 Cwd::realpath
. 실제로 세 가지 펄 함수가 있습니다. 단일 인수를 취하고 절대 경로 이름을 반환합니다. 아래 세부 사항은 Perl5> Core modules> Cwd 문서에서 가져온 것 입니다.
abs_path()
와 동일한 알고리즘을 사용합니다getcwd()
. 심볼릭 링크 및 상대 경로 구성 요소 (.
및..
)는에서 와 같이 표준 경로 이름을 반환하도록 확인됩니다realpath
.use Cwd 'abs_path'; my $abs_path = abs_path($file);
realpath()
의 동의어입니다.abs_path()
use Cwd 'realpath'; my $abs_path = realpath($file);
fast_abs_path()
더 위험하지만 잠재적으로 더 빠른 버전abs_path()
use Cwd 'fast_abs_path'; my $abs_path = fast_abs_path($file);
이 함수는 요청시에만 내보내 지므로 => arielf가 지적한 "Undefined subroutine" 오류 Cwd
를 방지하기 위해 사용 하십시오 . 이 세 가지 함수를 모두 가져 오려면 한 줄을 사용할 수 있습니다 .use Cwd
use Cwd qw(abs_path realpath fast_abs_path);
'realpath'를 살펴보십시오.
$ realpath
usage: realpath [-q] path [...]
$ realpath ../../../../../
/data/home
수년에 걸쳐이 문제를 여러 번 겪었고 이번에는 OSX와 Linux에서 사용할 수있는 순수한 bash 휴대용 버전이 필요했기 때문에 계속해서 다음을 작성했습니다.
살아있는 버전은 여기에 있습니다.
https://github.com/keen99/shell-functions/tree/master/resolve_path
하지만 그래서, 여기에 현재 버전이 있습니다 (잘 테스트되었다고 느낍니다 ..하지만 피드백에 열려 있습니다!)
평범한 bourne shell (sh)에서 작동하도록 만드는 것이 어렵지 않을 수도 있지만 시도하지 않았습니다. $ 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
}
다음은 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
이 함수를 사용하면 -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
도움이 될 수 있습니다.
$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);
참조 URL : https://stackoverflow.com/questions/4045253/converting-relative-path-into-absolute-path
'Nice programing' 카테고리의 다른 글
동적 키로 객체의 PropTypes 검사 (0) | 2021.01.05 |
---|---|
항목의 수평 배열이있는 WPF ListView? (0) | 2021.01.05 |
자바 스크립트 사전의 키는 값으로 저장되지 않고 변수 이름으로 저장됩니다. (0) | 2021.01.05 |
내부 클래스 라이브러리를 테스트하는 방법은 무엇입니까? (0) | 2021.01.05 |
Apache Spark 대 Akka (0) | 2021.01.05 |