Bash supporte un nombre surprenant d'opérations de manipulation de chaînes de caractères. Malheureusement, ces outils manquent d'unité. Certains sont un sous-ensemble de la substitution de paramètre et les autres font partie des fonctionnalités de la commande UNIX expr. Ceci produit une syntaxe de commande non unifiée et des fonctionnalités qui se recoupent, sans parler de la confusion engendrée.
Longueur de sous-chaînes correspondant à un motif au début d'une chaîne
$souschaine est une expression rationnelle.
$souschaine est une expression rationnelle.
chaineZ=abcABC123ABCabc # |------| # 12345678 echo `expr match "$chaineZ" 'abc[A-Z]*.2'` # 8 echo `expr "$chaineZ" : 'abc[A-Z]*.2'` # 8
Index
Position numérique dans $chaine du premier caractère dans $souschaine qui correspond.
chaineZ=abcABC123ABCabc # 123456 ... echo `expr index "$chaineZ" C12` # 6 # C position. echo `expr index "$chaineZ" 1c` # 3 # 'c' (à la position #3) correspond avant '1'.
Ceci est l'équivalent le plus proche de strchr() en C.
Extraction d'une sous-chaîne
Extrait une sous-chaîne de $chaine à partir de la position $position.
Si le paramètre $chaine est « * » ou « @ », alors cela extrait les paramètres de position, [39] commençant à $position.
Extrait $longueur caractères d'une sous-chaîne de $chaine à la position $position.
chaineZ=abcABC123ABCabc # 0123456789..... # indexage base 0. echo ${chaineZ:0} # abcABC123ABCabc echo ${chaineZ:1} # bcABC123ABCabc echo ${chaineZ:7} # 23ABCabc echo ${chaineZ:7:3} # 23A # Trois caractères de la sous-chaîne. # Est-il possible d'indexer à partir de la fin de la chaîne ? echo ${chaineZ:-4} # abcABC123ABCabc # Par défaut la chaîne complète, comme dans ${parametre:-default}. # Néanmoins... echo ${chaineZ:(-4)} # Cabc echo ${chaineZ: -4} # Cabc # Maintenant, cela fonctionne. # Des parenthèses ou des espaces ajoutés permettent un échappement du paramètre #+ de position. # Merci, Dan Jacobson, pour cette indication.
Les arguments position et longueur peuvent devenir des « paramètres », c'est-à-dire représentés par une variable, plutôt que par une constante numérique.
Si le paramètre $chaine est « * » ou « @ », alors ceci extrait un maximum de $longueur du paramètre de position, en commençant à $position.
echo ${*:2} # Affiche le deuxième paramètre de position et les suivants. echo ${@:2} # Identique à ci-dessus. echo ${*:2:3} # Affiche trois paramètres de position, en commençant par le deuxième.
Extrait $longueur caractères à partir de $chaine en commençant à $position.
chaineZ=abcABC123ABCabc # 123456789...... # indexage base 1. echo `expr substr $chaineZ 1 2` # ab echo `expr substr $chaineZ 4 3` # ABC
Extrait $souschaine à partir du début de $chaine, et où $souschaine est une expression rationnelle.
Extrait $souschaine à partir du début de $chaine, et où $souschaine est une expression rationnelle.
chaineZ=abcABC123ABCabc # ======= echo `expr match "$chaineZ" '\(.[b-c]*[A-Z]..[0-9]\)'` # abcABC1 echo `expr "$chaineZ" : '\(.[b-c]*[A-Z]..[0-9]\)'` # abcABC1 echo `expr "$chaineZ" : '\(.......\)'` # abcABC1 # Toutes les formes ci-dessus donnent un résultat identique.
Extrait $souschaine à la fin de $chaine, et où $souschaine est une expression rationnelle.
Extrait $souschaine à la fin de $chaine, et où $souschaine est une expression rationnelle.
chaineZ=abcABC123ABCabc # ====== echo `expr match "$chaineZ" '.*\([A-C][A-C][A-C][a-c]*\)'` # ABCabc echo `expr "$chaineZ" : '.*\(......\)'` # ABCabc
Suppression de sous-chaînes
Efface l'occurrence la plus courte de $souschaine à partir du début de $chaine.
Efface l'occurrence la plus longue de $souschaine à partir du début de $chaine.
chaineZ=abcABC123ABCabc # |----| la plus courte # |----------| la plus longue echo ${chaineZ#a*C} # 123ABCabc # Efface la plus courte occurrence entre 'a' et 'C'. echo ${chaineZ##a*C} # abc # Efface la plus longue occurrence entre 'a' et 'C'.
Efface la plus courte occurrence de $souschaine à partir de la fin de $chaine.
Par exemple :
# Renomme tous les fichiers de $PWD #+ en remplaçant le suffixe "TXT" par "txt". # Par exemple, "fichier1.TXT" devient "fichier1.txt" . . . SUFF=TXT suff=txt for i in $(ls *.$SUFF) do mv -f $i ${i%.$SUFF}.$suff # Ne modifie rien *en dehors* de l'occurrence la plus courte #+ commençant du côté droit de $i . . . done ### Ceci pourrait être condenser en une ligne si nécessaire. # Thank you, Rory Winston.
Efface la plus longue occurrence de $souschaine à partir de la fin de $chaine.
chaineZ=abcABC123ABCabc # || la plus courte # |------------| la plus longue echo ${chaineZ%b*c} # abcABC123ABCa # Coupe la plus courte occurrence entre 'b' et 'c', à partir de la fin #+ de $chaineZ. echo ${chaineZ%%b*c} # a # Coupe la plus courte occurrence entre 'b' et 'c', à partir de la fin #+ de $chaineZ.
Cet opérateur est utilisé pour générer des noms de fichier.
Exemple 9.12. Convertir des formats de fichiers graphiques avec une modification du nom du fichier
&cvt;
Une simple émulation de getopt en utilisant des constructions d'extraction de sous-chaînes.
Remplacement de sous-chaîne
Remplace la première occurrence de $souschaine par $remplacement. [40]
Remplace toutes les occurrences de $souschaine par $remplacement.
chaineZ=abcABC123ABCabc echo ${chaineZ/abc/xyz} # xyzABC123ABCabc # Remplace la première occurrence de #+ 'abc' par 'xyz'. echo ${chaineZ//abc/xyz} # xyzABC123ABCxyz # Remplace toutes les occurrences de #+ 'abc' par 'xyz'. echo --------------- echo "$chaineZ" # abcABC123ABCabc echo --------------- # La chaîne elle-même n'est pas modifiée ! # Le motif de recherche et le remplacement peuvent-ils être #+ paramétrisés ? motif=abc rempl=000 echo ${chaineZ/$motif/$rempl} # 000ABC123ABCabc # ^ ^ ^^^ echo ${chaineZ//$motif/$rempl} # 000ABC123ABC000 # Oui ! ^ ^ ^^^ ^^^ echo # Que se passe-t-il si aucune chaîne de remplacement n'est fournie ? echo ${chaineZ/abc} # ABC123ABCabc echo ${chaineZ//abc} # ABC123ABC # On obtient une suppression pure et simple.
Si $souschaine correspond au début de $chaine, substitue $remplacement à $souschaine.
Si $souschaine correspond à la fin de $chaine, substitue $remplacement à $souschaine.
chaineZ=abcABC123ABCabc echo ${chaineZ/#abc/XYZ} # XYZABC123ABCabc # Remplace la dernière occurrence de #+ 'abc' par 'XYZ'. echo ${chaineZ/%abc/XYZ} # abcABC123ABCXYZ # Remplace la dernière occurrence de #+ 'abc' par 'XYZ'.
Un script Bash peut utiliser des fonctionnalités de manipulation de chaînes de caractères de awk comme alternative à ses propres fonctions intégrées.
Pour plus d'informations sur la manipulation des chaînes de caractères dans les scripts, voyez la Section 9.3, « Substitution de paramètres » et la section de la liste des commandes consacrée à la commande expr.
Exemples de scripts :