web-dev-qa-db-fra.com

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

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, donc 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.

26
FunTomas

Utiliser awk pour 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 placez dans une variable Shell et utilisez la substitution de paramètres intégrée de bash:

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

La façon dont cela fonctionne est en supprimant un préfixe qui correspond avidement à '* /', qui est ce que le ## l'opérateur fait:

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

basename et dirname fonctionnent 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
22
Fedor Dikarev

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 la variable Shell, vous pouvez utiliser:

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

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 compacter cela en un seul python3 -c à utiliser 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 sauts de 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 (/); ajuster/tester si cela vous importe.)

6
Thanatos

Une méthode consiste à rev l'URL, puis coupez le champ, puis rev à nouveau. par exemple:

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

Production:

file.jar 

Exemple 2:

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

Production:

file.jar
1
Nived Thanima