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 produite une syntaxe de commande non unifié et des fonctionnalités qui se recoupent, sans parler de la confusion engendrée.
Longueur de chaînes de caractères
chaineZ=abcABC123ABCabc echo ${#chaineZ} # 15 echo `expr length $chaineZ` # 15 echo `expr "$chaineZ" : '.*'` # 15 |
Exemple 9-10. Insérer une ligne blanche entre les paragraphes d'un fichier texte
#!/bin/bash # paragraph-space.sh # Insère une ligne blanche entre les paragraphes d'un fichier texte. # Usage: $0 <NOMFICHIER LONGUEUR_MINI=45 # Il peut être nécessaire de changer cette valeur. # Suppose que les lignes plus petites que $LONGUEUR_MINI caractères #+ terminent un paragraphe. while read ligne # Pour toutes les lignes du fichier... do echo "$ligne" # Afficher la ligne. longueur=${#ligne} if [ "$longueur" -lt "$LONGUEUR_MINI" ] then echo # Ajoute une ligne blanche après chaque petite ligne. fi done exit 0 |
Longueur de sous-chaînes au début d'une chaîne
$souschaine est une expression régulière.
$souschaine est une expression régulière.
chaineZ=abcABC123ABCabc # |------| 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 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 strchr() en C.
Extraction d'une sous-chaîne
Extrait une sous-chaîne de $chaine à la position $position.
Si le paramètre $chaine est << * >> ou << @ >>, alors cela extrait les paramètres de position, [1] 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. |
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 régulière.
Extrait $souschaine à partir du début de $chaine, et où $souschaine est une expression régulière.
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 régulière.
Extrait $souschaine à la fin de $chaine, et où $souschaine est une expression régulière.
chaineZ=abcABC123ABCabc # ====== echo `expr match "$chaineZ" '.*\([A-C][A-C][A-C][a-c]*\)'` # ABCabc echo `expr "$chaineZ" : '.*\(......\)'` # ABCabc |
Suppression de sous-chaînes
Supprime la correspondance la plus petite de $souschaine à partir du début de $chaine.
Supprime la correspondance la plus grande de $souschaine à partir du début de $chaine.
chaineZ=abcABC123ABCabc # |----| # |----------| echo ${chaineZ#a*C} # 123ABCabc # Supprime la plus petite correspondance entre 'a' et 'C'. echo ${chaineZ##a*C} # abc # Supprime la plus grande correspondance entre 'a' et 'C'. |
Supprime la plus petite correspondance de $souschaine à partir de la fin de $chaine.
Supprime la plus grande correspondance de $souschaine à partir de la fin de $chaine.
chaineZ=abcABC123ABCabc # || # |------------| echo ${chaineZ%b*c} # abcABC123ABCa # Supprime la plus petite correspondance entre 'b' et 'c', à partir de la fin #+ de $chaineZ. echo ${chaineZ%%b*c} # a # Supprime la plus petite correspondance entre 'b' et 'c', à partir de la fin #+ de $chaineZ. |
Exemple 9-11. Convertir des formats de fichiers graphiques avec une modification du nom du fichier
#!/bin/bash # cvt.sh: # Convertit les fichiers image MacPaint contenues dans un répertoire dans un #+ format "pbm". # Utilise le binaire "macptopbm" provenant du paquetage "netpbm", #+ qui est maintenu par Brian Henderson (bryanh@giraffe-data.com). # Netpbm est un standard sur la plupart des distributions Linux. OPERATION=macptopbm SUFFIXE=pbm # Suffixe pour les nouveaux noms de fichiers. if [ -n "$1" ] then repertoire=$1 # Si le nom du répertoire donné en argument au script... else repertoire=$PWD # Sinon, utilise le répertoire courant. fi # Assume que tous les fichiers du répertoire cible sont des fichiers image # + MacPaint avec un suffixe ".mac". for fichier in $repertoire/* # Filename globbing. do nomfichier=${fichier%.*c} # Supprime le suffixe ".mac" du nom du fichier #+ ('.*c' correspond à tout ce qui se trouve #+ entre '.' et 'c', inclus). $OPERATION $fichier > $nomfichier.$SUFFIXE # Redirige la conversion vers le nouveau nom du fichier. rm -f $fichier # Supprime le fichier original après sa convertion. echo "$nomfichier.$SUFFIXE" # Trace ce qui se passe sur stdout. done exit 0 |
Remplacement de sous-chaîne
Remplace la première correspondance de $souschaine par $remplacement.
Remplace toutes les correspondances de $souschaine avec $remplacement.
chaineZ=abcABC123ABCabc echo ${chaineZ/abc/xyz} # xyzABC123ABCabc # Remplace la première correspondance de #+ 'abc' avec 'xyz'. echo ${chaineZ//abc/xyz} # xyzABC123ABCxyz # Remplace toutes les correspondances de #+ 'abc' avec 'xyz'. |
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 correspondance de fin de #+ 'abc' avec 'xyz'. echo ${chaineZ/%abc/XYZ} # abcABC123ABCXYZ # Remplace la correspondance de fin de #+ 'abc' avec '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.
Exemple 9-12. Autres moyens d'extraire des sous-chaînes
#!/bin/bash # substring-extraction.sh Chaine=23skidoo1 # 012345678 Bash # 123456789 awk # Notez les différents systèmes d'indexage de chaînes: # Bash compte le premier caractère d'une chaîne avec '0'. # Awk compte le premier caractère d'une chaîne avec '1'. echo ${Chaine:2:4} # position 3 (0-1-2), longueur de quatre caractères # skid # L'équivalent awk de ${string:pos:length} est substr(string,pos,length). echo | awk ' { print substr("'"${Chaine}"'",3,4) # skid } ' # Envoyé un "echo" vide à awk donne une entrée inutile, et donc permet d'éviter #+ d'apporter un nom de fichier. exit 0 |
Pour plus d'informations sur la manipulation des chaînes de caractères dans les scripts, référez-vous à la Section 9.3 et à la section consacrée à la commande expr. Pour des exemples de scripts, jetez un oeil sur :
[1] | Ceci s'applique soit aux arguments en ligne de commande soit aux paramètres passés à une fonction. |
Précédent | Sommaire | Suivant |
Variables internes | Niveau supérieur | Substitution des paramètres |