Como obter a última parte do link http no Bash?

25

Eu tenho um link http:

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

e quero salvar a última parte file.jar na variável, para que a sequência de saída seja "file.jar".

Condição : o link pode ter um comprimento diferente, por exemplo:

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

Eu tentei assim:

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

, mas o problema é o tamanho do URL, por isso preciso de um comando que possa ser usado para qualquer tamanho de URL.

FunTomas
fonte

Respostas:

51

Usar awkpara isso funcionaria, mas é como caçar veados com um obus. Se você já tem seu URL vazio, é muito simples fazer o que você deseja, se você o colocar em uma variável shell e usar basha substituição de parâmetro integrada:

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

A maneira como isso funciona é removendo um prefixo que corresponda avidamente '* /', que é o que o ##operador faz:

${haystack##needle} # removes any matching 'needle' from the
                    # beginning of the variable 'haystack'
DopeGhoti
fonte
Algum tipo de explicação a seguir?
Questionmark
Certo. Isso serve?
DopeGhoti 23/11
Isso é ótimo :)
Questionmark
2
Se você deseja extrair as strings de consulta, você pode primeiro atribuir a uma variável intermediária, por exemplo file=${myurl##*/}, em seguida, usar a correspondência reversa gulosa para fazer backup no ?(não se esqueça de escapar disso!), Por exemploecho ${file%%\?*}
Doktor J
21

basenamee dirnamefunciona bem também para URLs:

> 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
Fedor Dikarev
fonte
+1 Brilhante, funciona porque um URL e um PATH e os dois URIs.
Tulains Córdova
11
@ TulainsCórdova um caminho não é um URI ; isso funciona porque basenamee dirnamedivide as strings em /, e isso também funciona com URLs, pelo menos enquanto eles não tiverem uma parte local (embora não com URIs em geral).
Stephen Kitt
No artigo da Wikipedia sobre URIs, eles dão o seguinte como exemplos válidos de URI referências: /relative/URI/with/absolute/path/to/resource.txt, relative/path/to/resource.txt, ../../../resource.txte resource.txt en.wikipedia.org/wiki/...
Tulains Córdova
11
@ TulainsCórdova A Wikipedia não está errada, /relative/pathpode ser um caminho do sistema de arquivos ou um URI relativo. Mas qual deles depende do contexto. Quando é usado como um caminho do sistema de arquivos, não é um URI. Quando é usado como um URI, não é um caminho do sistema de arquivos. Dizer que é um URI apenas porque coincide com a sintaxe é como dizer que cada uma das palavras deste comentário também é um URI.
hvd 25/11
11

Com awk, você pode usar $NF, para obter o último campo, independentemente do número de campos:

awk -F / '{print $NF}'

Se você armazenar essa sequência na variável shell, poderá usar:

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

A maioria das respostas postadas não é robusta em URLs que contêm sequências de caracteres ou destinos de consulta, como, por exemplo, o seguinte:

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

Python possui análise de URL em sua biblioteca padrão; é mais fácil deixar fazer isso. Por exemplo,

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

Você pode compactar isso em um único python3 -cpara uso em um shell script:

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

(Você também pode manter o script dividido, para facilitar a leitura. 'Permitirá inserir novas linhas.)

Obviamente, agora seu script shell depende do Python.

(Estou um pouco inseguro sobre se isso tenta lidar com casos em que o componente do caminho da URL é a raiz ( /); ajuste / teste se isso for importante para você.)

Thanatos
fonte
1

Um método é revo URL, recorte o campo e, em seguida, revnovamente. por exemplo:

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

Saída:

file.jar 

Exemplo 2:

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

Saída:

file.jar
Nived Thanima
fonte