Как получить последнюю часть 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.

FunTomas
источник

Ответы:

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
источник
Любое объяснение, чтобы пойти с этим?
Вопросительный
Конечно. Будет ли это делать?
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.
Тулаинс Кордова
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.
августа
11

С помощью awkвы можете использовать $NF, чтобы получить последнее поле, независимо от количества полей:

awk -F / '{print $NF}'

Если вы храните эту строку в переменной оболочки, вы можете использовать:

a=http://www.test.com/abc/def/efg/file.jar
printf '%s\n' "${a##*/}"
cuonglm
источник
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

Один метод заключается revв URL, затем вырезать поле, а затем 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
Нивед Танима
источник