Odpowiedzi:
Możesz użyć readlinknarzędzia z -fopcją:
-f, --canonicalizecanonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
Niektóre dystrybucje, na przykład te, które używają GNU coreutils i FreeBSD , również zawierają realpath(1)narzędzie, które po prostu wywołuje realpath(3)i robi prawie to samo.
readlinknor realpath- w szczególności Solaris i HP-UX.
brew install coreutils apple.stackexchange.com/a/69332/23040 , a jeśli nie chcesz wykonać kroku przekierowującego wszystkie standardowe narzędzia Mac CLI do nowo zainstalowanych odpowiedników GNU, po prostu zadzwoń greadlink.
Przenośnie, PWDzmienna jest ustawiana przez powłokę na jedną bezwzględną lokalizację bieżącego katalogu. Każdy element tej ścieżki może być dowiązaniem symbolicznym.
case $f in
/*) absolute=$f;;
*) absolute=$PWD/$f;;
esac
Jeśli chcesz, aby wyeliminować .i ..jak dobrze, przejdź do katalogu zawierającego plik i uzyskać $PWDtam:
if [ -d "$f" ]; then f=$f/.; fi
absolute=$(cd "$(dirname -- "$f")"; printf %s. "$PWD")
absolute=${absolute%?}
absolute=$absolute/${f##*/}
Nie ma przenośnego sposobu na śledzenie dowiązań symbolicznych. Jeśli masz ścieżkę do katalogu, w większości jednorożców $(cd -- "$dir" && pwd -P 2>/dev/null || pwd)zapewnia ścieżkę, która nie używa dowiązań symbolicznych, ponieważ powłoki, które śledzą dowiązania symboliczne, mają tendencję do implementowania pwd -P(„P” dla „fizycznego”).
Niektóre jednorożce zapewniają narzędzie do drukowania „fizycznej” ścieżki do pliku.
readlink -f, podobnie jak FreeBSD ≥ 8.3, NetBSD ≥4,0 i OpenBSD już w wersji 2.2.realpath(jest także obecny na niektórych systemach Linux i jest w BusyBox).Jeśli Perl jest dostępny, możesz użyć Cwdmodułu .
perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/filepwd( $(cd -- "$dir" && pwd -P 2>/dev/null | pwd))? Wygląda na to, że nie obchodzi to standardowe wyjście.
||
Czy pwdpasuje do twoich potrzeb? Podaje bezwzględną ścieżkę do bieżącego katalogu. A może to, czego chcesz, to realpath () .
alisteri rss67w tym artykule przedstawiam najbardziej stabilny, kompatybilny i najłatwiejszy sposób. Nigdy przedtem nie widziałem lepszego sposobu.
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
Jeśli chcesz wrócić do pierwotnej lokalizacji,
ORGPATH=`pwd`
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd $ORGPATH
lub
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd -
Chciałbym, żeby to pomogło. To było dla mnie najlepsze rozwiązanie.
ABSPATH=$(cd -- "$RELPATH" && pwd). Zwróć uwagę na podwójne cudzysłowy wokół podstawienia (aby nie łamać, jeśli ścieżka zawiera białe znaki i znaki globowania) oraz --(w przypadku, gdy ścieżka zaczyna się od -). Działa to również tylko w przypadku katalogów i nie kanonizuje dowiązań symbolicznych zgodnie z żądaniem. Zobacz moją odpowiedź, aby uzyskać więcej informacji.
Inne odpowiedzi tutaj były w porządku, ale były niewystarczające dla moich potrzeb. Potrzebowałem rozwiązania, którego mógłbym użyć w moich skryptach na dowolnym komputerze. Moim rozwiązaniem było napisanie skryptu powłoki, który można wywoływać ze skryptów tam, gdzie są potrzebne.
#!/bin/sh
if [ $# -eq 0 ] || [ $# -gt 2 ]; then
printf 'Usage: respath path [working-directory]\n' >&2
exit 1
fi
cantGoUp=
path=$1
if [ $# -gt 1 ]; then
cd "$2"
fi
cwd=`pwd -P` #Use -P option to account for directories that are actually symlinks
#Handle non-relative paths, which don't need resolution
if echo "$path" | grep '^/' > /dev/null ; then
printf '%s\n' "$path"
exit 0
fi
#Resolve for each occurrence of ".." at the beginning of the given path.
#For performance, don't worry about ".." in the middle of the path.
while true
do
case "$path" in
..*)
if [ "$cwd" = '/' ]; then
printf 'Invalid relative path\n' >&2
exit 1
fi
if [ "$path" = '..' ]; then
path=
else
path=`echo "$path" | sed 's;^\.\./;;'`
fi
cwd=`dirname $cwd`
;;
*)
break
;;
esac
done
cwd=`echo "$cwd" | sed 's;/$;;'`
if [ -z "$path" ]; then
if [ -z "$cwd" ]; then
cwd='/'
fi
printf '%s\n' "$cwd"
else
printf '%s/%s\n' "$cwd" "$path"
fi
To rozwiązanie zostało napisane dla Bourne Shell pod kątem przenośności. Mam to w skrypcie o nazwie „respath.sh”.
Tego skryptu można użyć w następujący sposób:
respath.sh '/path/to/file'
Lub tak
respath.sh '/relative/path/here' '/path/to/resolve/relative/to'
Skrypt rozwiązuje ścieżkę w pierwszym argumencie, używając ścieżki z drugiego argumentu jako punktu początkowego. Jeśli podano tylko pierwszy argument, skrypt rozpoznaje ścieżkę względem bieżącego katalogu roboczego.
pwdwbudowaną i nie obsługuje -P(powłoka Bourne'a nie implementuje tej logicznej obsługi $ PWD jak powłoki POSIX).
cd -P --jeśli pierwszy argument zawiera trochę ..
caseczek powinien być ..|../*)zamiast ..*.
dirname $cwd
Odnosząc się do odpowiedzi wszystkich innych, znalazłem poniższą funkcję, która jest bardzo łatwa i przenośna między Linuksem / MAC OSX niż inne, które znalazłem wszędzie. Może komuś pomóc.
#!/usr/bin/bash
get_absolute_path(){
file_path=`pwd $1`
echo "$file_path/$1"
}
#to assign to a variable
absolute_path=$(get_absolute_path "file.txt")
echo $absolute_path
Załóżmy, że zmienna a przechowuje nazwę ścieżki (a = „cokolwiek”)
1. W przypadku potencjalnej ścieżki zawierającej przestrzeń:
c=$(grep -o " " <<< $a | wc -l); if (( $c > "0" )); then a=$(sed 's/ /\\ /g' <<< $a); fi
2. W przypadku rzeczywistego pytania, tj. Konwersji ścieżki na wartość bezwzględną: readlink może pobrać zawartość dowiązania symbolicznego, które można zastosować w następujący sposób. (uwaga readlink -fbyłaby idealna, ale nie jest dostępna przynajmniej w wersji bash dla Mac OS X, w której -f oznacza FORMATY ).
if [[ $(readlink $a) == "" ]]; then a=$(cd $a; pwd); else a=$(cd $(readlink $a); pwd); fi
3. Właśnie się nauczyłem pwd -Pw man pwd: -P ma „ Wyświetlić fizyczny bieżący katalog roboczy (wszystkie dowiązania symboliczne rozwiązane) ” i tym samym
if (( $(grep -o " " <<< $a | wc -l) > "0" )); then a=$(sed 's/ /\\ /g' <<< $a); fi; a=$(cd $a; pwd -P)
też będzie działać.
Wniosek: połącz 1 z 2, aby spełnić oba wymagania, a nazwy ścieżek zawierających spację zostały już omówione w bardziej zwięzłym 3 .
-fPrzełącznik nie istnieje w systemie Mac OS X (co najmniej od 10.8.5). Bez-fprzełącznika po prostu zwraca kod błędu.