Jak uzyskać ostatnią część linku http w Bash?


25

Mam link http:

http://www.test.com/abc/def/efg/file.jar 

i chcę zapisać ostatnią część file.jar w zmiennej, więc ciąg wyjściowy to „file.jar”.

Warunek : link może mieć inną długość, np .:

http://www.test.com/abc/def/file.jar.

Próbowałem w ten sposób:

awk -F'/' '{print $7}'

, ale problemem jest długość adresu URL, więc potrzebuję polecenia, którego można użyć dla dowolnej długości adresu URL.

Odpowiedzi:


51

Korzystanie awkz tego byłoby skuteczne, ale to rodzaj polowania na jelenie z haubicą. Jeśli masz już pusty adres URL, możesz zrobić to, co chcesz, jeśli umieścisz go w zmiennej powłoki i użyjesz bashwbudowanego podstawiania parametrów:

$ myurl='http://www.example.com/long/path/to/example/file.ext'
$ echo ${myurl##*/}
file.ext

Działa to poprzez usunięcie przedrostka, który łapczywie pasuje do „* /”, co ##robi operator:

${haystack##needle} # removes any matching 'needle' from the
                    # beginning of the variable 'haystack'

Jakieś wytłumaczenie z tym związane?
zapytania

Pewnie. Czy to zrobi?
DopeGhoti,

To wspaniale :)
zapytania

2
Jeśli chcesz usunąć ciągi zapytań, możesz najpierw przypisać zmienną pośrednią, np. file=${myurl##*/}Następnie użyć chciwego dopasowywania wstecznego, aby utworzyć kopię zapasową ?(nie zapomnij go uciec!), Np.echo ${file%%\?*}
Doktor J

21

basenamei dirnamedziała dobrze również w przypadku adresów URL:

> url="http://www.test.com/abc/def/efg/file.jar"
> basename "$url"; basename -s .jar "$url"; dirname "$url"
file.jar
file
http://www.test.com/abc/def/efg

+1 Genialne, działa, ponieważ URL i ŚCIEŻKA oraz oba URI.
Tulains Córdova

1
@ TulainsCórdova ścieżka nie jest identyfikatorem URI ; działa to, ponieważ basenamei dirnamedzieli ciągi znaków na /, i tak się dzieje, że działa również z adresami URL, przynajmniej tak długo, jak długo nie mają one części lokalnej (choć ogólnie nie z URI).
Stephen Kitt

W artykule Wikipedia o URI, dają następujące jako ważnych przykładów referencji URI: /relative/URI/with/absolute/path/to/resource.txt, relative/path/to/resource.txt, ../../../resource.txti resource.txt en.wikipedia.org/wiki/...
Tulains Córdova

1
@ TulainsCórdova Wikipedia nie jest błędna, /relative/pathmoże to być ścieżka systemu plików lub względny identyfikator URI. Ale który z nich zależy od kontekstu. Gdy jest używany jako ścieżka do systemu plików, nie jest to identyfikator URI. Gdy jest używany jako identyfikator URI, nie jest ścieżką do systemu plików. Powiedzenie, że jest to URI tylko dlatego, że zdarza się, że pasuje do składni, jest jak powiedzenie, że każde ze słów w tym komentarzu jest również URI.
hvd

11

Za pomocą awkmożna $NFuzyskać ostatnie pole niezależnie od liczby pól:

awk -F / '{print $NF}'

Jeśli przechowujesz ten ciąg w zmiennej powłoki, możesz użyć:

a=http://www.test.com/abc/def/efg/file.jar
printf '%s\n' "${a##*/}"

6

Większość opublikowanych odpowiedzi nie jest odporna na adresy URL zawierające ciągi lub cele zapytania, takie jak na przykład:

https://example.com/this/is/a/path?query#target

Python analizuje adresy URL w swojej standardowej bibliotece; łatwiej jest na to pozwolić. Na przykład,

from urllib import parse
import sys
path = parse.urlparse(sys.stdin.read().strip()).path
print("/" if not path or path == "/" else path.rsplit("/", 1)[-1])

Możesz skompaktować to w jeden python3 -cdo użycia w skrypcie powłoki:

echo 'https://example.com/this/is/a/path/componets?query#target' \
    | python3 -c 'from urllib import parse; import sys; path = parse.urlparse(sys.stdin.read().strip()).path; print("/" if not path or path == "/" else path.rsplit("/", 1)[-1])'

(Możesz również zachować skrypt w stanie rozbitym, aby był czytelny. 'Pozwoli ci wstawić nowe wiersze).

Oczywiście teraz twój skrypt powłoki jest zależny od Pythona.

(Nie jestem pewien, czy ta próba poradzi sobie z przypadkami, w których składową ścieżki URL jest root ( /); dostosuj / przetestuj, jeśli to dla Ciebie ważne).


1

Jedną z metod jest revadres URL, a następnie wyciąć pole, a następnie revponownie. na przykład:

echo 'http://www.test.com/abc/def/efg/file.jar ' | rev | cut -d '/' -f 1 | rev

Wydajność:

file.jar 

Przykład 2:

echo 'http://www.test.com/abc/cscsc/sccsc/def/efg/file.jar ' | rev | cut -d '/' -f 1 | rev

Wydajność:

file.jar
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.