Notez que la plupart des fonctionnalités décrites dans ce document (voire la totalité) sont spécifiques à bash et ne font pas partie de la norme POSIX. Elles ne fonctionneront donc pas avec d'autres interpréteurs de commandes.
Il est donc plus prudent de ne les utiliser que dans des scripts ad-hoc pour lesquels la dépendance à bash ne sera jamais un problème.
Extraire une sous-chaîne
Sur une chaîne de caractères
Bash permet d'extraire une partie d'une chaîne de caractère conservée dans une variable en utilisant ce type de syntaxe :
Si paramètres
est une chaîne de caractère, l'expression ci-dessus se
développe pour fournir la sous-chaîne débutant au caractère début
(le premier
étant 0
) et de longueur longueur
:
$ var="So long, and thanks for all the fish!"
$
[long]
À noter :
- si
longueur
n'est pas précisée, la sous-chaîne sera extraite de la positiondébut
jusuq'à la fin de la valeur deparamètre
:$ [thanks for all the fish!]
début
peut être un entier négatif, qui désignera alors une position à partir de la fin de la chaîne (le dernier caractère étant à la position-1
) :
Notez qu'il faut impérativement placer une espace après le premier$ var="So long, and thanks for all the fish!" $ [all]
:
pour éviter que bash ne confonde pas avec la syntaxe «${paramètre:-mot}
» (qui représente l'utilisation de valeur par défaut).- si
longueur
est négatif, il ne désignera alors plus la longueur de la sous-chaîne à extraire mais la position de la fin de la sous-chaîne à partir de la fin de la chaîne d'origine :$ var="So long, and thanks for all the fish!" $ [all]
début
etlongueur
sont évalués comme des expressions arithmétiques, ce qui peut être pratique (bien que cet exemple manque d'imagination) :$ var="So long, and thanks for all the fish!" $ i=3 $ [long]
Sur un tableau indicé
Utilisée avec un tableau indicé, cette fonctionnalité permet d'en extraire un sous-ensemble d'éléments. Par exemple, on récupèrera ainsi 2 éléments à partir de la position 3 du tableau indicé :
$ tableau=("zéro" "un" "deux" "trois" "quatre" "cinq")
$
trois quatre
En utilisant @
comme paramètre, on peut extraire un sous-ensemble des
paramètres du script ou de la fonction en cours (@
agit comme tout tableau
indicé) :
$ myfunc() { ; }
$ myfunc a b c d e
c d
Cette fonctionnalité n'est pas applicable sur un tableau associatif, son utilisation donnera un résultat indéfini.
Supprimer un préfixe
Sur une chaîne de caractères
Pour supprimer un motif du début d'une chaîne de caractères, on utilisera une syntaxe du type :
La première forme enlève le plus court motif correspondant, et la seconde le plus long.
Les motifs mentionnés ici et tout au long de ce document sont les motifs de
développements de chemin de bash (comme ceux utilisés dans une commande comme
ls *.txt
). Ils sont décrits en détail dans la section Développement des chemins
du manuel de
bash, en
français.
À noter aussi :
- ce motif peut bien sûr aussi être une simple chaîne de caractères :
$ var="So long, and thanks for all the fish!" $ and thanks for all the fish!
- ces motifs permettent par exemple de récupérer le nom de fichier à partir de
son chemin absolu (un peu comme le fait la commande
basename) :
$ fichier="/usr/share/doc/bash/INTRO.gz" $ INTRO.gz
- dans l'exemple ci-dessus, seule la suppression du plus long motif
correspondant (avec
##
) a un sens. La suppression du plus court motif (avec#
) donnerait le résultat suivant :$ fichier="/usr/share/doc/bash/INTRO.gz" $ usr/share/doc/bash/INTRO.gz
Sur un tableau
Appliquée à un tableau indicé, l'opération de suppression du préfixe est effectuée sur tous ses éléments :
$ tableau=(dossier_fry.txt dossier_leela.txt dossier_bender.txt)
$
fry.txt leela.txt bender.txt
Sur un tableau associatif, la transformation est également opérée sur toutes les valeurs du tableau, qui sont retournées sans leur clef et sans ordre particulier :
$ declare -A tableau
$ tableau=(["leela"]="dossier_leela.txt" ["fry"]="dossier_fry.txt" ["bender"]="dossier_bender.txt")
$
fry.txt leela.txt bender.txt
Supprimer un suffixe
Sur une chaîne de caractères
La syntaxe suivante permet de supprimer un motif à la fin d'une chaîne de caractères :
La première forme enlève le plus court motif correspondant, et la seconde le plus long (il s'agit bien sûr toujours des mêmes motifs que ceux des développement de chemins)
À noter aussi :
- le motif peut représenter une simple chaîne de caractères, par exemple :
$ var="So long, and thanks for all the fish!" $ So long, and thanks
- ces motifs permettent par exemple de récupérer le répertoire où se trouve un
fichier à partir de son chemin absolu (un peu comme le fait la commande
dirname) :
$ fichier="/usr/share/doc/bash/INTRO.gz" $ /usr/share/doc/bash
- attention, dans l'exemple ci-dessus, seule la suppression du motif le plus
court correspondant a un sens. La suppression du motif le plus long
supprimerait toute la chaîne :
$ fichier="/usr/share/doc/bash/INTRO.gz" $
- on peut également supprimer l'extention du nom d'un fichier (pour rappel, le
point n'a pas de signification particulière dans les les développements de
chemins de
bash,
contrairement aux expressions régulières) :
$ fichier="machin.txt" $ machin
Sur un tableau
Appliqué à un tableau indicé, cette opération est appliquée sur tous ses éléments :
$ tableau=(fry.txt leela.txt bender.txt)
$
fry leela bender
Sur un tableau associatif, la transformation est également opérée sur toutes les valeurs du tableau, qui sont retournées sans leur clef et sans ordre particulier :
$ declare -A tableau
$ tableau=(["fry"]="dossier_fry.txt" ["leela"]="dossier_leela.txt" ["bender"]="dossier_bender.txt")
$
dossier_fry dossier_leela dossier_bender
Remplacer un motif
Sur une chaîne de caractères
Pour remplacer un motif par une chaîne de caractère, on pourra utiliser la forme :
Par exemple, en utilisant une simple chaîne de caractères comme motif :
$ var="So long, and thanks for all the fish!"
$
So long, and thanks for all the scripts!
À noter :
- si
motif
commence par un/
(c'est à dire si le premier/
est doublé), toutes les correspondances sont remplacées, sinon seule la première l'est ; - si
motif
commence par#
, il doit correspondre au début de la chaîne ; - si
motif
commence par%
, il doit correspondre à la fin de la chaîne ; - si
chaîne
est vide, les portions correspondant au motif sont supprimées et le/
qui suitmotif
peut être omis.
Illustrations en exemples :
- un motif sans préfixe particulier remplace la première correspondance :
$ var="I see, ah ah ah" $ I see, XX ah ah
- un motif débutant par
/
remplace toutes les correspondances :$ var="I see, ah ah ah" $ I see, XX XX XX
- un motif débutant par
#
remplace une éventuelle correspondance en début de chaîne :$ var="I see, ah ah ah" I see, ah ah ah You see, ah ah ah
- un motif débutant par
%
remplace une éventuelle correspondance en fin de chaîne :$ var="I see, ah ah ah" I see, ah ah XX I see, ah ah ah
- si
chaîne
est vide, le dernier/
peut être omis, et le développement demotif
sera simplement supprimé de la chaîne (ou plutôt remplacé par la chaîne vide) :$ var="I see, ah ah ah" I see, ah ah! I see, !
Sur un tableau
Appliqué à un tableau indicé, cette manipulation est là encore effectuée sur tous ses éléments :
$ tableau=(fry_and_bender.txt leela_and_fry.txt bender_versus_flexo.txt)
$
fry_and_bender_the_best.txt leela_and_fry.txt bender_the_best_versus_flexo.txt
Sur un tableau associatif, la transformation est également opérée sur toutes les valeurs du tableau, qui sont retournées sans leur clef et sans ordre particulier :
$ declare -A tableau
$ tableau=(["leela"]="dossier_leela.txt" ["fry"]="dossier_fry.txt" ["bender"]="dossier_bender.txt")
$
dossier_fry.txt dossier_leela.txt dossier_bender_the_best.txt
Modifier la casse
Sur une chaîne de caractères
Pour changer la casse des caractères dans la valeur d'une variable, on pourra utiliser une syntaxe du type :
Le caractère ^
change les lettres en majuscules, et ,
en minuscules (pour
le retenir, pensez à une flèche vers le haut pour les majuscules, et vers le
bas pour les minuscules). Lorsqu'on double le caractère (^^
ou ,,
), toutes
les lettres de la chaîne sont examinées, sinon seule la première lettre de la
chaîne est affectée.
Cette fonctionnalité nécessite la version 4.0 ou supérieure de bash. À partir
de sa version 5.1, bash propose également une façon peut-être plus intuitive
de changer la casse de la valeur de paramètre
, sous la forme
${paramètre@opérateur}
, détaillée ci-dessous.
Pour l'expliquer plus précisément :
${paramètre^motif}
convertit en majuscule le premier caractère de la valeur deparamètre
si c'est une lettre et qu'elle correspond àmotif
;${paramètre^^motif}
convertit en majuscule toutes les lettres correspondant àmotif
dans la valeur deparamètre
;${paramètre,motif}
convertit en minuscule le premier caractère de la valeur deparamètre
si c'est une lettre et qu'elle correspond àmotif
;${paramètre,,motif}
convertit en minuscule toutes les lettres correspondant àmotif
dans la valeur deparamètre
.
Si motif
est vide dans les expressions ci-dessus (donc dans des expressions
comme ${paramètre^^}
, par exemple), le motif utilisé par défaut est ?
, qui
correspond à n'importe quelle lettre. Les lettres de la chaîne concernées par
l'opération sont donc systématiquement transformées.
Illustrations en exemples :
- pour convertir en majuscule la première lettre de
paramètre
si c'est une lettre et qu'elle correspond àmotif
:$ var="so long, and thanks for all the fish!" $ so long, and thanks for all the fish! $ So long, and thanks for all the fish!
- pour convertir en majuscules toutes les lettres de
paramètre
qui correspondent àmotif
:$ var="so long, and thanks for all the fish!" $ So long, and thankS for all the fiSh!
- pour convertir en majuscules toutes les lettres de
paramètre
:$ var="so long, and thanks for all the fish!" $ SO LONG, AND THANKS FOR ALL THE FISH!
- pour convertir en minuscule la première lettre de
paramètre
si elle correspond àmotif
:var="SO LONG, AND THANKS FOR ALL THE FISH!" SO LONG, AND THANKS FOR ALL THE FISH! sO LONG, AND THANKS FOR ALL THE FISH!
- pour convertir en minuscules toutes les lettres de
paramètre
qui correspondent àmotif
:$ var="SO LONG, AND THANKS FOR ALL THE FISH!" $ sO LONG, AND tHANKs FOR ALL tHE FIsH!
- pour convertir en minuscules toutes les lettres de
paramètre
:$ var="SO LONG, AND THANKS FOR ALL THE FISH!" $ so long, and thanks for all the fish!
Sur un tableau
Cette fonctionnalité peut être utilisée sur tableau indicé pour transformer chacun de ses éléments :
$ tableau=(fry leela bender farnsworth)
$
Fry Leela Bender Farnsworth
$
FRY LEELA BENDER FARNSWORTH
Sur un tableau associatif, la transformation est opérée sur toutes les valeurs du tableau, qui sont retournées sans leur clef et sans ordre particulier :
$ declare -A tableau
$ tableau=(["leela"]="dossier_leela.txt" ["fry"]="dossier_fry.txt" ["bender"]="dossier_bender.txt")
$
Dossier_fry.txt Dossier_leela.txt Dossier_bender.txt
$
DOSSIER_FRY.TXT DOSSIER_LEELA.TXT DOSSIER_BENDER.TXT
Modifier la casse (solution alternative)
Sur une chaîne de caractères
À partir de sa version 5.1, bash propose un opérateur de transformations sous
la forme ${paramètre@opérateur}
qui permet lui aussi de modifier la casse des
lettres de la valeur de paramètre
, grâce à ses opérateurs U
, u
, et L
.
Il ne permet toutefois pas de sélectionner les lettres à transformer avec un
motif :
${paramètre@U}
convertit en majuscules toutes les lettres de la valeur deparamètres
;${paramètre@u}
convertit en majuscule le premier caractère de la valeur deparamètres
, s'il s'agit d'une lettre ;${paramètre@L}
convertit en minuscules toutes les lettres de la valeur deparamètres
.
En voici les illustrations en exemples :
- pour convertir en majuscules toutes les lettres de
paramètre
:$ var="so long, and thanks for all the fish!" $ SO LONG, AND THANKS FOR ALL THE FISH!
- pour convertir en majuscule la première lettre de
paramètre
si c'est une lettre :
Notez que les autres lettres ne sont pas transformées en minucules :$ var="so long, and thanks for all the fish!" $ So long, and thanks for all the fish!
$ var="SO LONG, AND THANKS FOR ALL THE FISH!" $ SO LONG, AND THANKS FOR ALL THE FISH!
- pour convertir en minuscules toutes les lettres de
paramètre
:$ var="SO LONG, AND THANKS FOR ALL THE FISH!" $ so long, and thanks for all the fish!
Sur un tableau
Appliqué à un tableau, la transformation de casse est opérée sur chacun de ses élements :
- pour transformer en masjuscules toutes les lettres des éléments d'un tableau :
$ tableau=(fry leela bender farnsworth) $ FRY LEELA BENDER FARNSWORTH
- pour transformer en masjuscules le premier caractère de chaque éléments d'un
tableau, s'il s'agit d'une lettre :
$ tableau=(fry leela bender farnsworth) $ Fry Leela Bender Farnsworth
- pour transformer en minuscules toutes les lettres des éléments d'un tableau :
$ tableau=(FRY LEELA BENDER FARNSWORTH) $ fry leela bender farnsworth
L'opération fonctionne de la même manière sur un tableau associatif. La transformation est opérée sur toutes les valeurs du tableau, qui sont retournées sans leur clef et sans ordre particulier :
$ declare -A tableau
$ tableau=(["leela"]="dossier_leela.txt" ["fry"]="dossier_fry.txt" ["bender"]="dossier_bender.txt")
$
DOSSIER_FRY.TXT DOSSIER_LEELA.TXT DOSSIER_BENDER.TXT
Obtenir la longueur d'une variable
Sur une chaîne de caractères
Pour obtenir la longueur d'une chaîne de caractères conservée dans une
variable, on la préfixe par #
entre accolades :
$ var="So long, and thanks for all the fish!"
$
37
Sur un tableau
Avec un tableau indicé ou associatif, cette opération renvoit le nombre d'éléments qu'il contient :
$ tableau=(fry leela bender farnsworth)
$
4
$ declare -A tableau
$ tableau=(["fry"]="dossier_fry.txt" ["bender"]="dossier_bender.txt")
$
2