Jak uzyskać pełną ścieżkę pliku w bash?


23

Chciałbym w łatwy sposób uzyskać pełną ścieżkę do pliku. Obecnie piszę to:

echo `pwd`/file.ext

Próbując go skrócić, stworzyłem alias bash:

alias fp='echo `pwd`/'

Ale teraz, gdy piszę fp file.ext, między /i a pojawia się spacja file.ext.

Czy takie polecenie już istnieje i brakuje mi go? Jeśli nie, to jak bym stworzył taki alias lub funkcję w bash?

Odpowiedzi:


31

W systemach linuxowych powinieneś mieć readlinkzainstalowany projekt GNU coreutils i możesz to zrobić:

readlink -f file.ext

W systemach Debian / ubuntu może być zainstalowane narzędzie realpath , które „zapewnia w większości te same funkcje, co /bin/readlink -fw pakiecie coreutils”.


readlink -f(lub realpath, który jest starszym narzędziem zachowanym w celu zachowania zgodności) dodatkowo rozszerzy wszystkie dowiązania symboliczne, co niekoniecznie jest pożądane.
— Gilles „SO- przestań być zły”

8
fyi: nie działa na macosxie.
— akira,

Na moim komputerze Mac zainstalowałem Coreutils za pomocą HomeBrew i zawiera realpath.
— Doug Harris

7

Zamiast pwdpolecenia użyj PWDzmiennej (również w POSIX):

fp () {
  case "$1" in
    /*) printf '%s\n' "$1";;
    *) printf '%s\n' "$PWD/$1";;
  esac
}

Jeśli potrzebujesz obsługi systemu Windows, rozpoznawanie ścieżek bezwzględnych będzie bardziej skomplikowane, ponieważ każdy port narzędzi uniksowych ma własne reguły tłumaczenia ścieżek plików. W Cygwin użyj cygpathnarzędzia.


Może to twój wybór, ale ta funkcja nie wyświetla nowej linii.
— cyr

takie podejście ma tę zaletę, że wykorzystuje tylko wbudowane powłoki, co jest szybsze niż wywoływanie zewnętrznych plików binarnych. powinieneś wyjaśnić ten fakt nieco bardziej.
— akira

4

aby odpowiedzieć na twoje pytanie za pomocą tego, czego używasz teraz:

alias rozwija się w miejscu, w którym teraz piszesz. wpisałeś:

% fp<SPACE>file.ext

to się staje

% echo `pwd`<SPACE>file.exe

możesz użyć funkcji, aby tego uniknąć:

function fp() {
    echo `pwd`/"$1"
}

możesz użyć tego jak zwykle:

% fp file.ext

Potrzebujesz podwójnych cudzysłowów wokół podstawień zmiennych i poleceń:echo "`pwd`/$1"
— Gilles 'SO- przestań być zły'

@Gilles: w jakich okolicznościach?
— akira

2
@akira: Zawsze używaj podwójnych cudzysłowów, chyba że chcesz, aby wynik interpretacji był traktowany jako wzorzec globowania, a wyniki globbowania podzielone na słowa. Tutaj budujesz nazwę pojedynczego pliku, więc potrzebne są podwójne cudzysłowy (wypróbuj swoją funkcję z plikiem wywoływanym *w katalogu zawierającym inne pliki).
— Gilles „SO- przestań być zły”

„ ” jest globowane przez powłokę (w moim przypadku zsh) i rozszerzane, zanim wejdą w funkcję. fp *daje, /tmp/4cc3ea0c1b34bponieważ jest to pierwszy parametr funkcji. pozostałe parametry to inne pliki w katalogu. jak tylko mam plik o nazwie „ ” funkcja nadal działa zgodnie z oczekiwaniami, wywołując go za pomocą „*” lub * lub *
— akira,

bash jest tutaj „zły”, jak się wydaje, bash daje to, o czym mówisz.
— akira

3

Możesz użyć:

realpath file.ext

Nie mam tego. Skąd to pochodzi?
— frabjous

@frabjous: jest specyficzny dla Debiana i pochodnych i zostanie zainstalowany tylko, jeśli o to poprosiłeś lub pakiet, który jest od niego zależny.
— Gilles „SO- przestań być zły”

Używam Arch. To nie jest oparte na Debianie, ale i tak jest w nim pakiet. Nie jestem pewien, czy warto go zainstalować, jeśli mam już link do odczytu.
— frabjous

Cóż, to jest opcja; lub możesz rozważyć funkcję, patrz odpowiedź Gillesa . W każdym razie zależy to od tego, jak naprawdę chcesz z tym skorzystać (jestem ciekawy).
— cyr

@frabjous: Nie określiłeś systemu, na którym się znajdujesz, ale jeśli używa on menedżera pakietów opartego na Aptitude (Debian, Ubuntu, Mint, itp.), możesz wpisać, apt-cache search realpathaby ujawnić, że coreutils i zwykłe pakiety realpath oba zawierają to. Następnie możesz wpisać sudo apt-get install realpath(lub coreutils), aby go zainstalować.
— Michael Scheper,

1

Od /programming//a/3915420/5795941

To jedyny sposób, który jest dla mnie do zaakceptowania. Nie rozwija linków takich jak realpath i readlink i jest to klasyczny sposób robienia tego, który widziałem wszędzie.

#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.