Як отримати останню частину http-посилання на Bash?


25

У мене є http-посилання:

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

і я хочу зберегти останню частину file.jar до змінної, тому рядок виводу є "file.jar".

Умова : посилання може мати різну довжину, наприклад:

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

Я спробував це так:

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

, але проблема полягає в довжині URL-адреси, тому мені потрібна команда, яку можна використовувати для будь-якої довжини URL-адреси.

Відповіді:


51

Використання awkдля цього спрацювало б, але це свого роду полювання на оленів гаубицею. Якщо у вас вже є гола URL-адреса, зробити це просто потрібно, якщо ви помістите її в змінну оболонки та використовуєте bashвбудовану підстановку параметрів:

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

Як це працює, видаляючи префікс, який жадібно відповідає '* /', що ##робить оператор:

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

Якесь пояснення йти з цим?
питання

Звичайно. Це зробить?
DopeGhoti

Це чудово :)
питання

2
Якщо ви хочете зняти рядки запиту, ви можете спершу призначити проміжну змінну, наприклад file=${myurl##*/}, потім використовувати жадібну зворотну відповідність для резервного копіювання ?(не забудьте уникнути цього!), Наприкладecho ${file%%\?*}
Doktor J

21

basenameі dirnameдобре працюйте за 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 Блискуче, він працює, оскільки URL-адреса, PATH та обидва URI-адреси.
Tulains Córdova

1
@ TulainsCórdova шлях не є URI ; Це працює , тому basenameі dirnameрозщеплені рядки на /, і що відбувається з роботи з URL , теж, по крайней мере до тих пір , поки вони не мають локальну частину (ні з URI , в загальному , хоча).
Стівен Кітт

У статті Вікіпедії про URIs, вони дають такі як дійсні приклади посилань URI: /relative/URI/with/absolute/path/to/resource.txt, relative/path/to/resource.txt, ../../../resource.txtі resource.txt en.wikipedia.org/wiki / ...
Tulains Córdova

1
@ TulainsCórdova Вікіпедія не є помилкою, це /relative/pathможе бути шлях до файлової системи або відносний URI. Але для кого з них це залежить від контексту. Коли він використовується як шлях до файлової системи, це не URI. Коли він використовується як URI, це не шлях до файлової системи. Скажімо, що це URI лише тому, що трапляється відповідати синтаксису - це як сказати, що кожне зі слів у цьому коментарі також є URI.
hvd

11

З awk, ви можете використовувати $NFостаннє поле незалежно від кількості полів:

awk -F / '{print $NF}'

Якщо ви зберігаєте цей рядок у змінній оболонки, ви можете використовувати:

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

6

Більшість опублікованих відповідей не є надійними для URL-адрес, що містять рядки запитів або цілі, такі як, наприклад, такі:

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

Python має розбір URL-адрес у своїй стандартній бібліотеці; простіше дозволити це зробити. Наприклад,

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])

Ви можете їх ущільнити в сингл python3 -cдля використання в сценарії оболонки:

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])'

(Ви також можете тримати сценарій розбитим для читабельності. ' вам вставити нові рядки.)

Звичайно, тепер ваш скрипт оболонки залежить від Python.

(Я трохи не впевнений у тому, якщо це намагається обробити випадки, коли компонент шляху URL є коренем ( /); коригувати / перевірити, якщо це має значення для вас.)


1

Один із способів полягає в тому, щоб revURL-адреса вирізала поле, а потім revзнову. наприклад:

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

Вихід:

file.jar 

Приклад 2:

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

Вихід:

file.jar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.