¿Cómo obtener la última parte del enlace http en Bash?

25

Tengo un enlace http:

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

y quiero guardar la última parte file.jar en variable, por lo que la cadena de salida es "file.jar".

Condición : el enlace puede tener una longitud diferente, por ejemplo:

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

Lo intenté de esa manera:

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

, pero el problema es la longitud de la URL, por lo que necesito un comando que pueda usarse para cualquier longitud de URL.

FunTomas
fuente

Respuestas:

51

Usar awkpara esto funcionaría, pero es una especie de caza de ciervos con un obús. Si ya tiene su URL desnuda, es bastante simple hacer lo que quiere si la coloca en una variable de shell y utiliza bashla sustitución de parámetros incorporada:

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

La forma en que esto funciona es eliminando un prefijo que coincida con avidez con '* /', que es lo ##que hace el operador:

${haystack##needle} # removes any matching 'needle' from the
                    # beginning of the variable 'haystack'
DopeGhoti
fuente
¿Algún tipo de explicación para ir con eso?
Questionmark el
Seguro. ¿Eso hará?
DopeGhoti
Eso es genial :)
Questionmark
2
Si desea eliminar las cadenas de consulta, primero puede asignar a una variable intermedia, por ejemplo file=${myurl##*/}, luego usar la codiciosa coincidencia inversa para hacer una copia de seguridad de ?(¡no se olvide de escapar!), Por ejemploecho ${file%%\?*}
Doktor J
21

basenamey dirnamefunciona bien para las URL también:

> 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
fuente
+1 Brillante, funciona porque una URL y una RUTA y ambos URI.
Tulains Córdova
1
@ TulainsCórdova un camino no es un URI ; esto funciona porque basenamey dirnamedivide cadenas en /, y eso también funciona con URL, al menos siempre que no tengan una parte local (no con URI en general).
Stephen Kitt
En el artículo de Wikipedia sobre los URI, se dan los siguientes como ejemplos válidos de referencias URI: /relative/URI/with/absolute/path/to/resource.txt, relative/path/to/resource.txt, ../../../resource.txty resource.txt en.wikipedia.org/wiki/...
Tulains Córdova
1
@ TulainsCórdova Wikipedia no está mal, /relative/pathpuede ser una ruta del sistema de archivos o un URI relativo. Pero cuál de ellos es depende del contexto. Cuando se usa como una ruta del sistema de archivos, no es un URI. Cuando se usa como un URI, no es una ruta del sistema de archivos. Decir que es un URI solo porque coincide con la sintaxis es como decir que cada una de las palabras en este comentario también es un URI.
hvd
11

Con awk, puede usar $NF, para obtener el último campo, independientemente del número de campos:

awk -F / '{print $NF}'

Si almacena esa cadena en la variable de shell, puede usar:

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

La mayoría de las respuestas publicadas no son sólidas en las URL que contienen cadenas de consulta u objetivos, como, por ejemplo, lo siguiente:

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

Python tiene análisis de URL en su biblioteca estándar; Es más fácil dejarlo hacerlo. P.ej,

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

Puede compactarlo en un solo python3 -cpara usar en un script de shell:

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

(También puede mantener el guión desglosado, también, para 'facilitar la lectura. Le permitirá poner nuevas líneas).

Por supuesto, ahora su script de shell depende de Python.

(Estoy un poco inseguro sobre si trata de manejar casos donde el componente de ruta de la URL es la raíz ( /); ajustar / probar si eso es importante para usted).

Thanatos
fuente
1

Un método es revla URL, luego corta el campo y luego revnuevamente. p.ej:

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

Salida:

file.jar 

Ejemplo 2

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

Salida:

file.jar
Nived Thanima
fuente