Comment obtenir la dernière partie du lien http dans Bash?

25

J'ai un lien http:

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

et je veux enregistrer la dernière partie file.jar dans une variable, de sorte que la chaîne de sortie est "file.jar".

Condition : le lien peut avoir une longueur différente, par exemple:

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

Je l'ai essayé de cette façon:

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

, mais le problème est la longueur de l'URL, j'ai donc besoin d'une commande qui peut être utilisée pour n'importe quelle longueur d'URL.

FunTomas
la source

Réponses:

51

Utiliser awkpour cela fonctionnerait, mais c'est une sorte de chasse au cerf avec un obusier. Si vous avez déjà votre URL à nu, il est assez simple de faire ce que vous voulez si vous la mettez dans une variable shell et utilisez bashla substitution de paramètres intégrée de:

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

La façon dont cela fonctionne consiste à supprimer un préfixe qui correspond avec avidité à '* /', ce que fait l' ##opérateur:

${haystack##needle} # removes any matching 'needle' from the
                    # beginning of the variable 'haystack'
DopeGhoti
la source
Une sorte d'explication pour aller avec ça?
Questionmark
Sûr. Cela fera-t-il?
DopeGhoti
C'est super :)
Questionmark
2
Si vous souhaitez supprimer les chaînes de requête, vous pouvez d'abord les affecter à une variable intermédiaire, par exemple file=${myurl##*/}, puis utiliser la correspondance inverse gourmande pour sauvegarder la ?(n'oubliez pas de l'échapper!), Par exempleecho ${file%%\?*}
Doktor J
21

basenameet dirnamefonctionne aussi bien pour les 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
Fedor Dikarev
la source
+1 Brillant, cela fonctionne car une URL et un CHEMIN et les deux URI.
Tulains Córdova
1
@ TulainsCórdova un chemin n'est pas un URI ; cela fonctionne parce que basenameet dirnamedivise les chaînes sur /, et cela se produit également avec les URL, au moins tant qu'elles n'ont pas de partie locale (pas avec les URI en général cependant).
Stephen Kitt
Dans l'article Wikipedia URIs, ils donnent les exemples suivants valides de références URI: /relative/URI/with/absolute/path/to/resource.txt, relative/path/to/resource.txt, ../../../resource.txtet resource.txt en.wikipedia.org/wiki/...
Tulains Córdova
1
@ TulainsCórdova Wikipedia n'a pas tort, /relative/pathpeut être soit un chemin d'accès au système de fichiers, soit un URI relatif. Mais lequel de ceux-ci dépend du contexte. Lorsqu'il est utilisé comme chemin d'accès au système de fichiers, ce n'est pas un URI. Lorsqu'il est utilisé comme URI, ce n'est pas un chemin d'accès au système de fichiers. Dire qu'il s'agit d'un URI simplement parce qu'il correspond à la syntaxe revient à dire que chacun des mots de ce commentaire est également un URI.
DVD
11

Avec awk, vous pouvez utiliser $NF, pour obtenir le dernier champ, quel que soit le nombre de champs:

awk -F / '{print $NF}'

Si vous stockez cette chaîne dans une variable shell, vous pouvez utiliser:

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

La plupart des réponses publiées ne sont pas fiables sur les URL qui contiennent des chaînes de requête ou des cibles, telles que, par exemple, les suivantes:

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

Python a l'analyse d'URL dans sa bibliothèque standard; il est plus facile de le laisser faire. Par exemple,

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

Vous pouvez compresser cela en un seul python3 -cpour une utilisation dans un script 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])'

(Vous pouvez également conserver le script éclaté, pour plus de lisibilité. 'Vous permettra de mettre des retours à la ligne.)

Bien sûr, maintenant votre script shell dépend de Python.

(Je ne suis pas certain de savoir si cela essaie de gérer les cas où le composant de chemin d'accès de l'URL est la racine ( /); ajustez / testez si cela vous intéresse.)

Thanatos
la source
1

Une méthode consiste à revl'URL, puis coupez le champ, puis à revnouveau. par exemple:

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

Sortie:

file.jar 

Exemple 2:

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

Sortie:

file.jar
Nived Thanima
la source