IX. Chaînes de caractères

IX-1. Protection de caractères

Tuto réalisé par Eric Sanchis – maître de conférence à l’Université Toulouse 1 Sciences Sociales.

Le shell utilise différents caractères particuliers pour effectuer ses propres traitements ($ pour la substitution, > pour la redirection de la sortie standard, * comme caractère générique, etc.). Pour utiliser ces caractères particuliers comme de simples caractères, il est nécessaire de les protéger de l’interprétation du shell. Trois mécanismes sont utilisables :

Protection d’un caractère à l’aide du caractère \

Ce caractère protège le caractère qui suit immédiatement le caractère \.

Sélectionnez

Ex : $ echo \* => le caractère * perd sa signification de caractère générique
*
$ echo *
tata toto
$
$ echo \\ => le deuxième caractère \ perd sa signification de caractère de protection
\
$ echo N\'oublie pas !
N'oublie pas !
$

Rq : dans les exemples de cette section, les caractères en vert ont perdu leur signification particulière, les caractères en rouge sont interprétés.

Le caractère \ permet également d’ôter la signification de la touche Entrée. Cela a pour effet d’aller à la ligne sans qu’il y ait exécution de la commande. En effet, après saisie d’une commande, l’utilisateur demande au shell l’exécution de celle-ci en appuyant sur cette touche. Annuler l’interprétation de la touche Entrée autorise l’utilisateur à écrire une longue commande sur plusieurs lignes.

Dans l’exemple ci-dessous, le shell détecte que la commande interne echo n’est pas terminée ; par conséquent, bash affiche une chaîne d’appel différente matérialisée par un caractère > suivi d’un caractère espace invitant l’utilisateur à continuer la saisie de sa commande.

Sélectionnez

Ex : $ echo coucou \Entrée
> salut Entrée => terminaison de la commande : le shell l'exécute !
coucou salut
$

Protection de caractères à l’aide d’une paire de guillemets « chaîne »

Tous les caractères de chaîne sauf $ \ `  » sont protégés de l’interprétation du shell. Cela signifie, par exemple, qu’à l’intérieur d’une paire de guillemets le caractère $ sera quand même interprété comme une substitution, etc.

Sélectionnez

Ex : $ echo "< * $PWD * >"
< * /home/sanchis * >
$
$ echo "< * \"$PWD\" * > "
< * "/home/sanchis" * >
$

Protection totale ‘chaîne’

Entre une paire d’apostrophes (‘), aucun caractere de chaine (sauf le caractere ‘) n’est interprete.

Sélectionnez

Ex : $ echo '< * $PWD * >'
< * $PWD * >
$

IX-2. Longueur d’une chaîne de caractères

Sélectionnez

Syntaxe : ${#paramètre}

Cette syntaxe est remplacée par la longueur de la chaîne de caractères contenue dans paramètre. Ce dernier peut être une variable, un paramètre spécial ou un paramètre de position.

Sélectionnez

Ex : $ echo $PWD
/h
ome/sanchis $ echo ${#PWD}
14 => longueur de la chaîne /home/sanchis
$
$ set "au revoir"
$ echo ${#1}
9 => la valeur de $1 étant au revoir, sa longueur est 9
$
$ ls >/dev/null
$
$ echo ${#?}
1 => contenue dans $?, la valeur du code de retour de ls
$ => est 0, par conséquent la longueur est 1IX. Chaînes de caractères
▲
IX-1. Protection de caractères
▲

Le shell utilise différents caractères particuliers pour effectuer ses propres traitements ($ pour la substitution, > pour la redirection de la sortie standard, * comme caractère générique, etc.). Pour utiliser ces caractères particuliers comme de simples caractères, il est nécessaire de les protéger de l'interprétation du shell. Trois mécanismes sont utilisables :

Protection d'un caractère à l'aide du caractère \

Ce caractère protège le caractère qui suit immédiatement le caractère \.
 
Sélectionnez

Ex : $ echo \* => le caractère * perd sa signification de caractère générique
*
$ echo *
tata toto
$
$ echo \\ => le deuxième caractère \ perd sa signification de caractère de protection
\
$ echo N\'oublie pas !
N'oublie pas !
$

Rq : dans les exemples de cette section, les caractères en vert ont perdu leur signification particulière, les caractères en rouge sont interprétés.

Le caractère \ permet également d'ôter la signification de la touche Entrée. Cela a pour effet d'aller à la ligne sans qu'il y ait exécution de la commande. En effet, après saisie d'une commande, l'utilisateur demande au shell l'exécution de celle-ci en appuyant sur cette touche. Annuler l'interprétation de la touche Entrée autorise l'utilisateur à écrire une longue commande sur plusieurs lignes.

Dans l'exemple ci-dessous, le shell détecte que la commande interne echo n'est pas terminée ; par conséquent, bash affiche une chaîne d'appel différente matérialisée par un caractère > suivi d'un caractère espace invitant l'utilisateur à continuer la saisie de sa commande.
 
Sélectionnez

Ex : $ echo coucou \Entrée
> salut Entrée => terminaison de la commande : le shell l'exécute !
coucou salut
$

Protection de caractères à l'aide d'une paire de guillemets "chaîne"

Tous les caractères de chaîne sauf $ \ ` " sont protégés de l'interprétation du shell. Cela signifie, par exemple, qu'à l'intérieur d'une paire de guillemets le caractère $ sera quand même interprété comme une substitution, etc.
 
Sélectionnez

Ex : $ echo "< * $PWD * >"
< * /home/sanchis * >
$
$ echo "< * \"$PWD\" * > "
< * "/home/sanchis" * >
$

Protection totale 'chaîne'

Entre une paire d'apostrophes ('), aucun caractere de chaine (sauf le caractere ') n'est interprete.
 
Sélectionnez

Ex : $ echo '< * $PWD * >'
< * $PWD * >
$

IX-2. Longueur d'une chaîne de caractères
▲
 
Sélectionnez

Syntaxe : ${#paramètre}

Cette syntaxe est remplacée par la longueur de la chaîne de caractères contenue dans paramètre. Ce dernier peut être une variable, un paramètre spécial ou un paramètre de position.
 
Sélectionnez

Ex : $ echo $PWD
/h
ome/sanchis $ echo ${#PWD}
14 => longueur de la chaîne /home/sanchis
$
$ set "au revoir"
$ echo ${#1}
9 => la valeur de $1 étant au revoir, sa longueur est 9
$
$ ls >/dev/null
$
$ echo ${#?}
1 => contenue dans $?, la valeur du code de retour de ls
$ => est 0, par conséquent la longueur est 1

IX-3. Modificateurs de chaînes
▲

Les modificateurs de chaînes permettent la suppression d'une sous-chaîne de caractères correspondant à un modèle exprimé à l'aide de caractères ou d'expressions génériques.

Suppression de la plus courte sous-chaîne à gauche
 
Sélectionnez

Syntaxe : ${paramètre#modèle}

 
Sélectionnez

Ex : $ echo $PWD
/home/sanchis
$
$ echo ${PWD#*/}
home/sanchis => le premier caractère / a été supprimé
$
$ set "12a34a"
$
$ echo ${1#*a}
34a => suppression de la sous-chaîne 12a
$

Suppression de la plus longue sous-chaîne à gauche
 
Sélectionnez

Syntaxe : ${paramètre##modèle}

Ex : $ echo $PWD
/home/sanchis
$
$ echo ${PWD##*/}
sanchis => suppression de la plus longue sous-chaîne à gauche se
$ => terminant par le caractère /
$ set 12a34ab
$
$ echo ${1##*a}
b
$

Suppression de la plus courte sous-chaîne à droite
 
Sélectionnez

Syntaxe : ${paramètre%modèle}

Ex: $ echo $PWD
/home/sanchis
$ echo ${PWD%/*}
/home
$

Suppression de la plus longue sous-chaîne à droite
 
Sélectionnez

Syntaxe : ${paramètre%%modèle}
Ex : $ eleve="Pierre Dupont::12:10::15:9"
$
$ echo ${eleve%%:*}
Pierre Dupont
$

La variable eleve contient les prénom, nom et diverses notes d'un élève. Les différents champs sont séparés par un caractère deux-points. Il peut manquer des notes à un élève (cela se caractérise par un champ vide).

Exercices :

1. En utilisant les modificateurs de chaînes,

    écrire un programme shell touslesutil qui lit le contenu du fichier /etc/passwd et affiche le nom des utilisateurs enregistrés.
    modifier ce programme (soit touslesutiluid) pour qu'il affiche le nom et l'uid de chaque utilisateur.

2. En utilisant les modificateurs de chaînes,

écrire un programme shell basenom ayant un fonctionnement similaire à la commande unix basename. Cette commande affiche le dernier élément d'un chemin passé en argument. Il n'est pas nécessaire que ce chemin existe réellement.
 
Sélectionnez

Ex : $ basename /toto/tata/tutu
tutu
$

b) si un suffixe est mentionné comme deuxième argument, celui ci est également ôté de l'élément par la commande basename.
 
Sélectionnez

Ex : $ basename /toto/tata/tutu/prog.c .c
prog
$

Ecrire un programme basenom1 qui se comporte de la même manière.

3. Ecrire une commande dirnom, similaire à la commande unix dirname ; la commande unix dirname peut être vue comme la commande complémentaire à basename car dirname supprime le dernier élément d'un chemin; si cela donne la chaîne vide, alors le caractère . est affiché.
 
Sélectionnez

Ex : $ dirname /home/sanchis/bin
/home/sanchis
$
$ dirname toto
$

IX-4. Extraction de sous-chaînes
▲
 
Sélectionnez

${paramètre:ind} :

extrait de la valeur de paramètre la sous - chaîne débutant à l'indice ind. La valeur de paramètre n'est pas modifiée.

Attention : l'indice du premier caractère d'une chaîne est 0
 
Sélectionnez

Ex : ch="abcdefghijk" echo ${ch:3} affiche defghijk
01234567..10
${paramètre:ind:nb} : extrait nb caractères à partir de l'indice ind
Ex : $ echo ${ch:8:2}
ij
$ set ABCDEFGH
$
$ echo ${1:4:3}
EFG
$

Exercice : a) Ecrire un programme calibre prenant deux arguments, une chaîne de caractères ch et un nombre nb, qui affiche les nb premiers caractères de ch. Aucune erreur ne doit être traitée.

b) Modifier le programme précédent, soit calibre1, pour qu'il vérifie que :

- le nombre d'arguments est correct

- le deuxième argument est un nombre (suite non vide de chiffres).
IX-5. Remplacement de sous-chaînes
▲
 
Sélectionnez

${paramètre/mod/ch} :

bash recherche dans la valeur de paramètre la plus longue sous-chaîne satisfaisant le modèle mod puis remplace cette sous-chaîne par la chaîne ch. Seule la première sous-chaîne trouvée est remplacée. La valeur de paramètre n'est pas modifiée. Caractères et expressions génériques peuvent être présents dans mod.

Ce mécanisme de remplacement comprend plusieurs aspects :

(1) Remplacement de la première occurrence
 
Sélectionnez

Ex : $ v=totito
$ echo ${v/to/lo}
lotito
$

La valeur de la variable v (totito) contient deux occurrences du modèle to. Seule la première occurrence est remplacée par la chaîne lo.
 
Sélectionnez

Ex : $ set topo
$ echo $1
topo
$
$ echo ${1/o/i}
tipo
$

(2) Remplacement de la plus longue sous-chaîne
 
Sélectionnez

Ex : $ v=abcfefg
$ v1=${v/b*f/toto} => utilisation du caractère générique *
$ echo $v1
atotog
$

Deux sous-chaînes de v satisfont le modèle b*f : bcf et bcfef

C'est la plus longue qui est remplacée par toto.
 
Sélectionnez

${paramètre//mod/ch} :

contrairement à la syntaxe précédente, toutes les occurrences (et non seulement la première) satisfaisant le modèle mod sont remplacées par la chaîne ch
 
Sélectionnez

Ex : $ var=tobatoba
$ echo ${var//to/tou}
toubatouba
$
$ set topo
$ echo $1
topo
$
$ echo ${1//o/i}
tipi
$

 
Sélectionnez

${paramètre//mod/} :

lorsque la chaîne ch est absente, la première ou toutes les occurrences (suivant la syntaxe utilisée) sont supprimées
 
Sélectionnez

Ex : $ v=123azer45ty
$ shopt –s extglob
$ echo ${v//+([[:lower:]])/}
12345
$

L'expression générique +([[:lower:]] désigne la plus longue suite non vide de minuscules. La syntaxe utilisée signifie que toutes les occurrences doivent être traitées : la variable v contient deux occurrences (azer et ty). Le traitement à effectuer est la suppression.

Il est possible de préciser si l'on souhaite l'occurrence cherchée en début de chaîne de paramètre (syntaxe à utiliser : #mod) ou bien en fin de chaîne (%mod).
 
Sélectionnez

Ex : $ v=automoto
$ echo ${v/#aut/vel}
velomoto
$
$ v=automoto
$ echo ${v/%to/teur}
automoteur
$

IX-3. Modificateurs de chaînes

Les modificateurs de chaînes permettent la suppression d’une sous-chaîne de caractères correspondant à un modèle exprimé à l’aide de caractères ou d’expressions génériques.

Suppression de la plus courte sous-chaîne à gauche

Sélectionnez

Syntaxe : ${paramètre#modèle}

Sélectionnez

Ex : $ echo $PWD
/home/sanchis
$
$ echo ${PWD#*/}
home/sanchis => le premier caractère / a été supprimé
$
$ set "12a34a"
$
$ echo ${1#*a}
34a => suppression de la sous-chaîne 12a
$

Suppression de la plus longue sous-chaîne à gauche

Sélectionnez

Syntaxe : ${paramètre##modèle}

Ex : $ echo $PWD
/home/sanchis
$
$ echo ${PWD##*/}
sanchis => suppression de la plus longue sous-chaîne à gauche se
$ => terminant par le caractère /
$ set 12a34ab
$
$ echo ${1##*a}
b
$

Suppression de la plus courte sous-chaîne à droite

Sélectionnez

Syntaxe : ${paramètre%modèle}

Ex: $ echo $PWD
/home/sanchis
$ echo ${PWD%/*}
/home
$

Suppression de la plus longue sous-chaîne à droite

Sélectionnez

Syntaxe : ${paramètre%%modèle}
Ex : $ eleve="Pierre Dupont::12:10::15:9"
$
$ echo ${eleve%%:*}
Pierre Dupont
$

La variable eleve contient les prénom, nom et diverses notes d’un élève. Les différents champs sont séparés par un caractère deux-points. Il peut manquer des notes à un élève (cela se caractérise par un champ vide).

Exercices :

1. En utilisant les modificateurs de chaînes,

  1. écrire un programme shell touslesutil qui lit le contenu du fichier /etc/passwd et affiche le nom des utilisateurs enregistrés.
  2. modifier ce programme (soit touslesutiluid) pour qu’il affiche le nom et l’uid de chaque utilisateur.

2. En utilisant les modificateurs de chaînes,

écrire un programme shell basenom ayant un fonctionnement similaire à la commande unix basename. Cette commande affiche le dernier élément d’un chemin passé en argument. Il n’est pas nécessaire que ce chemin existe réellement.

Sélectionnez

Ex : $ basename /toto/tata/tutu
tutu
$

b) si un suffixe est mentionné comme deuxième argument, celui ci est également ôté de l’élément par la commande basename.

Sélectionnez

Ex : $ basename /toto/tata/tutu/prog.c .c
prog
$

Ecrire un programme basenom1 qui se comporte de la même manière.

3. Ecrire une commande dirnom, similaire à la commande unix dirname ; la commande unix dirname peut être vue comme la commande complémentaire à basename car dirname supprime le dernier élément d’un chemin; si cela donne la chaîne vide, alors le caractère . est affiché.

Sélectionnez

Ex : $ dirname /home/sanchis/bin
/home/sanchis
$
$ dirname toto
$

IX-4. Extraction de sous-chaînes

Sélectionnez

${paramètre:ind} :

extrait de la valeur de paramètre la sous – chaîne débutant à l’indice ind. La valeur de paramètre n’est pas modifiée.

Attention : l’indice du premier caractère d’une chaîne est 0

Sélectionnez

Ex : ch="abcdefghijk" echo ${ch:3} affiche defghijk
01234567..10
${paramètre:ind:nb} : extrait nb caractères à partir de l'indice ind
Ex : $ echo ${ch:8:2}
ij
$ set ABCDEFGH
$
$ echo ${1:4:3}
EFG
$

Exercice : a) Ecrire un programme calibre prenant deux arguments, une chaîne de caractères ch et un nombre nb, qui affiche les nb premiers caractères de ch. Aucune erreur ne doit être traitée.

b) Modifier le programme précédent, soit calibre1, pour qu’il vérifie que :

– le nombre d’arguments est correct

– le deuxième argument est un nombre (suite non vide de chiffres).

IX-5. Remplacement de sous-chaînes

Sélectionnez

${paramètre/mod/ch} :

bash recherche dans la valeur de paramètre la plus longue sous-chaîne satisfaisant le modèle mod puis remplace cette sous-chaîne par la chaîne ch. Seule la première sous-chaîne trouvée est remplacée. La valeur de paramètre n’est pas modifiée. Caractères et expressions génériques peuvent être présents dans mod.

Ce mécanisme de remplacement comprend plusieurs aspects :

(1) Remplacement de la première occurrence

Sélectionnez

Ex : $ v=totito
$ echo ${v/to/lo}
lotito
$

La valeur de la variable v (totito) contient deux occurrences du modèle to. Seule la première occurrence est remplacée par la chaîne lo.

Sélectionnez

Ex : $ set topo
$ echo $1
topo
$
$ echo ${1/o/i}
tipo
$

(2) Remplacement de la plus longue sous-chaîne

Sélectionnez

Ex : $ v=abcfefg
$ v1=${v/b*f/toto} => utilisation du caractère générique *
$ echo $v1
atotog
$

Deux sous-chaînes de v satisfont le modèle b*f : bcf et bcfef

C’est la plus longue qui est remplacée par toto.

Sélectionnez

${paramètre//mod/ch} :

contrairement à la syntaxe précédente, toutes les occurrences (et non seulement la première) satisfaisant le modèle mod sont remplacées par la chaîne ch

Sélectionnez

Ex : $ var=tobatoba
$ echo ${var//to/tou}
toubatouba
$
$ set topo
$ echo $1
topo
$
$ echo ${1//o/i}
tipi
$

Sélectionnez

${paramètre//mod/} :

lorsque la chaîne ch est absente, la première ou toutes les occurrences (suivant la syntaxe utilisée) sont supprimées

Sélectionnez

Ex : $ v=123azer45ty
$ shopt –s extglob
$ echo ${v//+([[:lower:]])/}
12345
$

L’expression générique +([[:lower:]] désigne la plus longue suite non vide de minuscules. La syntaxe utilisée signifie que toutes les occurrences doivent être traitées : la variable v contient deux occurrences (azer et ty). Le traitement à effectuer est la suppression.

Il est possible de préciser si l’on souhaite l’occurrence cherchée en début de chaîne de paramètre (syntaxe à utiliser : #mod) ou bien en fin de chaîne (%mod).

Sélectionnez

Ex : $ v=automoto
$ echo ${v/#aut/vel}
velomoto
$
$ v=automoto
$ echo ${v/%to/teur}
automoteur
$

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.

Retour en haut