Bash: pobiera ścieżkę bezwzględną podaną względną
Czy istnieje polecenie, aby pobrać ścieżkę bezwzględną podaną ścieżką względną?
Na przykład chcę, aby $line zawierała ścieżkę bezwzględną KAŻDEGO pliku w katalogu ./etc/
find ./ -type f | while read line; do
echo $line
done
16 answers
Użycie:
find $(pwd)/ -type f
Aby pobrać wszystkie pliki lub
echo $(pwd)/$line
Aby wyświetlić pełną ścieżkę (jeśli względna ścieżka ma znaczenie)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-13 23:34:39
Spróbuj realpath
.
~ $ sudo apt-get install realpath
~ $ realpath .bashrc
/home/username/.bashrc
Odpowiedź pochodzi z " polecenie bash/fish do wypisania bezwzględnej ścieżki do pliku ".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:25
Jeśli masz zainstalowany pakiet coreutils, możesz użyć readlink -f relative_file_name
, aby odzyskać absolutny (z rozwiązanymi wszystkimi dowiązaniami symbolicznymi)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-13 13:13:50
#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
UPD niektóre wyjaśnienia
- ten skrypt otrzymuje ścieżkę względną jako argument
"$1"
- następnie otrzymujemy dirname część tej ścieżki (możesz przekazać do tego skryptu katalog lub plik):
dirname "$1"
- następnie
cd "$(dirname "$1")
do tego względnego katalogu i uzyskujemy dla niego ścieżkę absolutną, uruchamiającpwd
polecenie powłoki - następnie dodajemy basename do ścieżki absolutnej:
$(basename "$1")
- jako ostatni krok możemy
echo
to
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-05 10:00:58
Jeśli to coś warte, głosowałem za wybraną odpowiedzią, ale chciałem podzielić się rozwiązaniem. Minusem jest to, że jest to tylko Linux - spędziłem około 5 minut próbując znaleźć odpowiednik OSX przed przejściem do Stack overflow. Na pewno gdzieś tam jest.
Na Linuksie można używać readlink -e
w połączeniu z dirname
.
$(dirname $(readlink -e ../../../../etc/passwd))
/etc/
A potem używasz siostry dirname
, basename
, aby po prostu
nazwa pliku
$(basename ../../../../../passwd)
passwd
Put it all razem..
F=../../../../../etc/passwd
echo "$(dirname $(readlink -e $F))/$(basename $F)"
/etc/passwd
Jesteś bezpieczny, jeśli celujesz w katalog, basename
nic nie zwróci
i skończysz z podwójnymi ukośnikami w końcowym wyjściu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-12 17:32:46
Myślę, że to jest najbardziej przenośne:
abspath() {
cd "$(dirname "$1")"
printf "%s/%s\n" "$(pwd)" "$(basename "$1")"
cd "$OLDPWD"
}
Nie powiedzie się, jeśli ścieżka nie istnieje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-28 22:43:44
realpath
jest chyba najlepszy
Ale ...
Pierwsze pytanie było bardzo mylone na początku, z przykładzie słabo związane z pytaniem, jak stwierdzono.
Wybrana odpowiedź faktycznie odpowiada podanemu przykładowi, a nie w ogóle pytanie w tytule. Pierwszym poleceniem jest odpowiedź (czy to naprawdę ? Wątpię), i równie dobrze poradziłby sobie bez"/". I nie widzę co robi drugie dowództwo.
Kilka kwestii jest mieszanych :
Zmiana względnej nazwy ścieżki na absolutną, niezależnie od tego oznacza, prawdopodobnie nic. (zazwyczaj, jeśli wydasz polecenie takie jak
touch foo/bar
, pathnamefoo/bar
musi istnieć dla Ciebie i być ewentualnie użyte w obliczenia, zanim plik zostanie faktycznie utworzony.)Może istnieć kilka bezwzględnych ścieżek oznaczających ten sam plik (lub potencjalnym pliku), zwłaszcza ze względu na dowiązania symboliczne (dowiązania symboliczne) na drodze, ale być może z innych powodów (a urządzenie może być montowane dwa razy jako Tylko do odczytu). Można lub nie chce się rozstrzygnąć explicity takie dowiązania symboliczne.
Przejście do końca łańcucha dowiązań symbolicznych do dowiązania nie-symbolicznego plik lub nazwa. To może, ale nie musi, dać bezwzględną nazwę ścieżki, w zależności od tego, jak to się robi. I ktoś może, lub nie chce przekształć go w ścieżkę bezwzględną.
Komenda readlink foo
bez opcji daje odpowiedź tylko wtedy, gdy jej
argument foo
jest dowiązaniem symbolicznym, a odpowiedź jest wartość tego
symlink. Nie ma innego linku. Odpowiedź może być ścieżką względną:
niezależnie od wartości argumentu dowiązania symbolicznego.
Jednak readlink
ma opcje (- f-E lub-M), które będą działać dla wszystkich
plików, i podać jedną ścieżkę bezwzględną (tą bez dowiązań symbolicznych) do
plik faktycznie oznaczony argumentem.
To działa dobrze dla wszystkiego, co nie jest dowiązaniem symbolicznym, choć można
chęć użycia bezwzględnej ścieżki bez rozwiązywania pośredniego
dowiązania symboliczne na ścieżce. Jest to wykonywane przez polecenie realpath -s foo
W przypadku argumentu dowiązania symbolicznego, {[5] } z jego opcjami będzie
ponownie rozwiąż wszystkie dowiązania symboliczne na bezwzględnej ścieżce do argumentu, ale
obejmie również wszystkie dowiązania symboliczne, które mogą być napotkane przez
po wartości argumentu. Możesz tego nie chcieć, jeśli chcesz
bezwzględna ścieżka do samego argumentu dowiązania symbolicznego, a nie do tego, co
może łączyć się z. Ponownie, jeśli foo
jest dowiązaniem symbolicznym, realpath -s foo
będzie
uzyskać ścieżkę bezwzględną bez rozwiązywania dowiązań symbolicznych, w tym the one
podane jako argument.
Bez opcji -s
, realpath
robi prawie to samo co
readlink
, z wyjątkiem zwykłego odczytu wartości odnośnika, a także kilku
inne rzeczy. Nie jest dla mnie jasne dlaczego readlink
ma swoje
opcji, tworząc pozornie niepożądaną redundancję z
realpath
.
Wniosek: realpath
jest najlepszym poleceniem do użycia, z najbardziej
elastyczność, przynajmniej w odniesieniu do żądanego tutaj zastosowania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 06:44:20
ODPOWIEDŹ Eugena nie do końca mi odpowiadała, ale to się udało:
absolute="$(cd $(dirname $file); pwd)/$(basename $file)"
Na marginesie, Twój bieżący katalog roboczy nie ma wpływu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-13 20:45:43
W przypadku find
najprościej jest podać absolutną ścieżkę do wyszukiwania, np.:
find /etc
find `pwd`/subdir_of_current_dir/ -type f
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-13 23:33:04
Jeśli używasz bash na Mac OS X, który nie istnieje ani realpath ani jego readlink może wydrukować ścieżkę bezwzględną, możesz mieć wybór, ale kodować własną wersję, aby ją wydrukować. Oto moja realizacja:
(pure bash)
abspath(){
local thePath
if [[ ! "$1" =~ ^/ ]];then
thePath="$PWD/$1"
else
thePath="$1"
fi
echo "$thePath"|(
IFS=/
read -a parr
declare -a outp
for i in "${parr[@]}";do
case "$i" in
''|.) continue ;;
..)
len=${#outp[@]}
if ((len==0));then
continue
else
unset outp[$((len-1))]
fi
;;
*)
len=${#outp[@]}
outp[$len]="$i"
;;
esac
done
echo /"${outp[*]}"
)
}
(use gawk)
abspath_gawk() {
if [[ -n "$1" ]];then
echo $1|gawk '{
if(substr($0,1,1) != "/"){
path = ENVIRON["PWD"]"/"$0
} else path = $0
split(path, a, "/")
n = asorti(a, b,"@ind_num_asc")
for(i in a){
if(a[i]=="" || a[i]=="."){
delete a[i]
}
}
n = asorti(a, b, "@ind_num_asc")
m = 0
while(m!=n){
m = n
for(i=1;i<=n;i++){
if(a[b[i]]==".."){
if(b[i-1] in a){
delete a[b[i-1]]
delete a[b[i]]
n = asorti(a, b, "@ind_num_asc")
break
} else exit 1
}
}
}
n = asorti(a, b, "@ind_num_asc")
if(n==0){
printf "/"
} else {
for(i=1;i<=n;i++){
printf "/"a[b[i]]
}
}
}'
fi
}
(pure BSD awk)
#!/usr/bin/env awk -f
function abspath(path, i,j,n,a,b,back,out){
if(substr(path,1,1) != "/"){
path = ENVIRON["PWD"]"/"path
}
split(path, a, "/")
n = length(a)
for(i=1;i<=n;i++){
if(a[i]==""||a[i]=="."){
continue
}
a[++j]=a[i]
}
for(i=j+1;i<=n;i++){
delete a[i]
}
j=0
for(i=length(a);i>=1;i--){
if(back==0){
if(a[i]==".."){
back++
continue
} else {
b[++j]=a[i]
}
} else {
if(a[i]==".."){
back++
continue
} else {
back--
continue
}
}
}
if(length(b)==0){
return "/"
} else {
for(i=length(b);i>=1;i--){
out=out"/"b[i]
}
return out
}
}
BEGIN{
if(ARGC>1){
for(k=1;k<ARGC;k++){
print abspath(ARGV[k])
}
exit
}
}
{
print abspath($0)
}
Przykład:
$ abspath I/am/.//..//the/./god/../of///.././war
/Users/leon/I/the/war
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-22 07:39:44
Moim ulubionym rozwiązaniem było to autorstwa @ EugenKonkov, ponieważ nie oznaczało to obecności innych narzędzi (pakiet coreutils).
Ale nie powiodło się dla ścieżek względnych "."i "..", więc oto nieco ulepszona wersja obsługująca te szczególne przypadki.
To nadal nie powiedzie się, jeśli użytkownik nie ma uprawnień do cd
do katalogu nadrzędnego ścieżki względnej.
#! /bin/sh
# Takes a path argument and returns it as an absolute path.
# No-op if the path is already absolute.
function to-abs-path {
local target="$1"
if [ "$target" == "." ]; then
echo "$(pwd)"
elif [ "$target" == ".." ]; then
echo "$(dirname "$(pwd)")"
else
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
fi
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 11:38:10
To, co powiedzieli, z wyjątkiem find $PWD
lub (w bash) find ~+
jest nieco wygodniejsze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-13 23:44:12
Podobne do odpowiedzi @ ernest-a, ale bez wpływu $OLDPWD
lub zdefiniowania nowej funkcji można odpalić subshell (cd <path>; pwd)
$ pwd
/etc/apache2
$ cd ../cups
$ cd -
/etc/apache2
$ (cd ~/..; pwd)
/Users
$ cd -
/etc/cups
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-13 09:26:41
Jeśli ścieżka względna jest ścieżką katalogu, spróbuj mine, powinna być najlepsza:
absPath=$(pushd ../SOME_RELATIVE_PATH_TO_Directory > /dev/null && pwd && popd > /dev/null)
echo $absPath
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-13 09:37:55
Jeśli chcesz przekształcić zmienną zawierającą ścieżkę względną w ścieżkę absolutną, działa to:
dir=`cd "$dir"`
" cd " odbija się echem bez zmiany katalogu roboczego, ponieważ jest wykonywany tutaj w pod-powłoce.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-25 05:21:42
echo "mydir/doc/ mydir/usoe ./mydir/usm" | awk '{ split($0,array," "); for(i in array){ system("cd "array[i]" && echo $PWD") } }'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 10:50:12