Linux / Commande basename : extraire un nom et retirer un suffixe
basename retire la partie répertoire d’un chemin pour afficher son dernier nom. Vous pouvez aussi retirer un suffixe connu, par exemple basename /donnees/archive.tar.gz .gz, qui donne archive.tar ; aucun fichier n’est ouvert, renommé ou vérifié par cette opération.
Le programme transforme une chaîne de caractères. Il reste donc utile pour préparer une étiquette à partir d’un chemin inexistant, mais son résultat ne prouve pas qu’un fichier correspondant existe ou qu’il est accessible.
Extraire le dernier composant d’un chemin
basename /var/log/nginx/access.log
basename /home/alice/Documents/
basename relatif/rapport.txt
Les résultats sont respectivement access.log, Documents et rapport.txt. Les barres obliques finales sont traitées avant l’extraction du nom. Le programme n’a pas à savoir si Documents est un véritable répertoire.
Pour transmettre un chemin avec espaces ou commençant par un tiret à GNU basename, protégez la valeur et terminez les options :
env QUOTING_STYLE=literal basename -- '/srv/documents/rapport annuel.pdf'
basename -- -rapport.txt
Les guillemets conservent un seul argument ; -- évite que -rapport.txt soit interprété comme une option. La première commande demande explicitement une présentation littérale. Des versions récentes de GNU Coreutils, dont le manuel 9.12, décrivent une citation de type shell-escape sur le terminal ; cette présentation peut différer de celle d’une sortie capturée.
Pour contrôler l’implémentation et les options disponibles :
basename --version
basename --help
Retirer un suffixe exact
Utiliser le second argument
basename /donnees/archive.tar.gz .gz
basename /donnees/archive.tar.gz .tar.gz
basename /donnees/rapport.txt .txt
Ces commandes donnent archive.tar, archive et rapport. Le suffixe est une chaîne littérale, pas un motif générique ni une expression régulière. La comparaison distingue les majuscules et les minuscules.
Si le nom se termine par .txt.bak, demander le retrait de .txt ne change rien : le suffixe doit être à la fin. Une absence de correspondance n’est pas une erreur du programme.
basename /donnees/rapport.txt.bak .txt
basename /donnees/IMAGE.JPG .jpg
basename /donnees/.txt .txt
Les résultats restent rapport.txt.bak, IMAGE.JPG et .txt. Le dernier cas est une exception utile : si le suffixe est égal au nom entier restant, basename ne le retire pas pour fabriquer une chaîne vide. Les barres obliques finales étant traitées avant cette étape, un suffixe contenant une barre oblique ne sert pas à retirer un morceau de répertoire.
Traiter plusieurs noms avec -s
basename -s .jpg -- /images/a.jpg /sauvegarde/b.jpg
basename --suffix=.log -- /var/log/app.log /tmp/test.log
L’option GNU -s, ou --suffix, applique le suffixe à chaque nom et active le traitement de plusieurs arguments. Les résultats de la première commande sont a et b ; ceux de la seconde sont app et test.
Ne déduisez pas une extension de chaque point rencontré. .profile est un nom caché habituel, archive.tar.gz porte plusieurs suffixes possibles et un nom peut finir par un point. Choisissez la règle de votre traitement avant de retirer des caractères.
Comprendre les entrées particulières
| Chaîne donnée | Résultat sans suffixe | Interprétation |
|---|---|---|
docs/manuel.pdf |
manuel.pdf |
Dernier composant d’un chemin relatif. |
docs/// |
docs |
Les séparateurs finaux sont retirés. |
notes.txt |
notes.txt |
Aucun répertoire à retirer. |
/ |
/ |
Cas de la racine. |
. ou .. |
. ou .. |
Ces chaînes ne sont pas résolues vers un autre chemin. |
| Chaîne vide. | Chaîne vide avec GNU basename. | Ne pas confondre avec l’absence totale d’argument. |
Le cas // dépend de la plate-forme, qui peut le distinguer de /. La spécification POSIX laisse aussi une latitude pour la chaîne vide. Si ces entrées sont possibles dans un programme portable, définissez votre comportement attendu et vérifiez l’implémentation.
basename ''
basename
Le premier appel GNU traite un argument vide et produit une ligne vide dans sa sortie littérale. Le second manque d’argument et échoue. Un résultat vide ne doit donc pas être interprété à lui seul comme une panne de la commande.
La spécification POSIX de basename définit l’ordre de traitement et les cas particuliers. Elle ne demande pas au programme de juger si la chaîne désigne un fichier valide.
Traiter plusieurs chemins et conserver les séparateurs
Activer explicitement plusieurs arguments
basename -a -- /srv/www/index.html /var/log/syslog /home/alice
La commande produit les trois noms index.html, syslog et alice. Sans -a ou -s, le second opérande est le suffixe : basename chemin1 chemin2 n’est pas une demande de deux noms.
Placez les options GNU avant les opérandes. Les extensions -a, -s et -z ne doivent pas être supposées disponibles dans toutes les versions Unix ; le format portable de base utilise un chemin et un suffixe optionnel.
Utiliser une sortie NUL dans un script Bash complet
Un nom peut contenir un saut de ligne sur Linux. L’option GNU -z, ou --zero, termine chaque résultat par l’octet NUL plutôt que par un saut de ligne. Ce script complet affiche des noms sans perdre leurs limites :
#!/usr/bin/env bash
if [ "$#" -eq 0 ]; then
printf '%s\n' 'Usage : bash afficher-noms.sh chemin [chemin...]' >&2
exit 64
fi
set -o pipefail
env QUOTING_STYLE=literal basename -z -a -- "$@" |
while IFS= read -r -d '' nom; do
printf 'Nom : %q\n' "$nom"
done
Enregistrez-le dans un nouveau fichier afficher-noms.sh, puis lancez :
bash afficher-noms.sh '/srv/rapport annuel.pdf' /tmp/archive.tar.gz
bash afficher-noms.sh $'/tmp/ligne1\nligne2.txt'
Le premier appel affiche deux noms ; le second traite le saut de ligne comme une partie d’un seul nom. printf '%q' montre une représentation protégée pour Bash. Aucune création de fichier n’est nécessaire pour ces exemples, puisque basename manipule les chaînes données.
"$@" conserve la séparation entre les arguments. IFS=, read -r et -d '' conservent les espaces, les barres obliques inverses et les sauts de ligne dans un élément. Le style littéral est demandé explicitement au producteur.
pipefail évite de cacher un échec de basename derrière la réussite de la boucle. Le code 64 est choisi par ce script pour une absence d’arguments. -z modifie la sortie de basename ; il ne lui ajoute pas un lecteur de listes NUL sur l’entrée standard.
Comparer basename, dirname et les expansions du shell
basename conserve le dernier nom, tandis que dirname retire ce nom et donne la partie répertoire. Pour /home/alice/rapport.txt, les résultats sont rapport.txt et /home/alice ; pour un simple notes.txt, dirname retourne normalement un point.
Le guide de dirname, disponible en anglais détaille ces règles. Ne supposez pas qu’assembler les deux résultats avec une barre oblique recrée exactement la chaîne d’origine : séparateurs répétés, séparateurs finaux et entrées spéciales peuvent avoir été traités.
chemin='/srv/rapport.pdf'
nom=${chemin##*/}
printf '%s\n' "$nom"
L’expansion du shell retire ici le plus long préfixe correspondant au motif qui finit par une barre oblique. Pour cette chaîne, le résultat est rapport.pdf, sans lancer un processus basename.
chemin='/srv/dossier/'
printf '<%s>\n' "${chemin##*/}"
basename -- "$chemin"
L’expansion produit une valeur vide, alors que basename donne dossier. À la racine, les deux méthodes diffèrent aussi. Les expansions de retrait de suffixe du shell utilisent des motifs ; elles ne constituent pas un remplacement général identique au suffixe littéral de basename.
De plus, nom=$(basename -- "$chemin") retire les sauts de ligne finaux par la substitution de commande. Si vous devez conserver exactement un nom qui en contient, préférez un consommateur NUL comme celui présenté plus haut. Le guide de pwd et de la conservation des chemins dans Bash explique cette propriété de la substitution.
Éviter les erreurs de sens dans l’automatisation
- Un fichier inexistant produit un nom. C’est normal : un test d’existence ou d’accès est une opération différente.
- Le suffixe reste présent. Contrôlez la fin exacte du nom, sa casse et l’exception du suffixe égal au nom entier. Un motif comme '*.txt' passé entre guillemets n’est pas une expression générique pour ce suffixe.
- Deux chemins donnent le même résultat. /a/rapport.txt et /b/rapport.txt deviennent tous deux rapport.txt. Ne construisez pas une copie ou un renommage sans politique de collision à partir du seul dernier nom.
- Les arguments sont découpés. Protégez les variables par des guillemets et gardez les arguments distincts. Un astérisque développé par le shell est déjà remplacé par une liste avant que basename ne démarre.
Le manuel GNU de basename décrit les options et le format de sortie. Pour décider ensuite d’ouvrir, déplacer ou publier un fichier, conservez son chemin complet et appliquez les vérifications propres à cette opération.




